Skip to content

Commit e85e1dc

Browse files
feat: Add support for Codespace Machines APIs (#3890)
1 parent 67e5f7b commit e85e1dc

File tree

4 files changed

+280
-0
lines changed

4 files changed

+280
-0
lines changed

github/codespaces_machines.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// Copyright 2025 The go-github AUTHORS. All rights reserved.
2+
//
3+
// Use of this source code is governed by a BSD-style
4+
// license that can be found in the LICENSE file.
5+
6+
package github
7+
8+
import (
9+
"context"
10+
"fmt"
11+
)
12+
13+
// CodespacesMachines represent a list of machines.
14+
type CodespacesMachines struct {
15+
TotalCount int64 `json:"total_count"`
16+
Machines []*CodespacesMachine `json:"machines"`
17+
}
18+
19+
// ListRepoMachineTypesOptions represent options for ListMachineTypesForRepository.
20+
type ListRepoMachineTypesOptions struct {
21+
// Ref represent the branch or commit to check for prebuild availability and devcontainer restrictions.
22+
Ref *string `url:"ref,omitempty"`
23+
// Location represent the location to check for available machines. Assigned by IP if not provided.
24+
Location *string `url:"location,omitempty"`
25+
// ClientIP represent the IP for location auto-detection when proxying a request
26+
ClientIP *string `url:"client_ip,omitempty"`
27+
}
28+
29+
// ListRepositoryMachineTypes lists the machine types available for a given repository based on its configuration.
30+
//
31+
// GitHub API docs: https://docs.github.com/rest/codespaces/machines#list-available-machine-types-for-a-repository
32+
//
33+
//meta:operation GET /repos/{owner}/{repo}/codespaces/machines
34+
func (s *CodespacesService) ListRepositoryMachineTypes(ctx context.Context, owner, repo string, opts *ListRepoMachineTypesOptions) (*CodespacesMachines, *Response, error) {
35+
u := fmt.Sprintf("repos/%v/%v/codespaces/machines", owner, repo)
36+
u, err := addOptions(u, opts)
37+
if err != nil {
38+
return nil, nil, err
39+
}
40+
41+
req, err := s.client.NewRequest("GET", u, nil)
42+
if err != nil {
43+
return nil, nil, err
44+
}
45+
46+
var machines *CodespacesMachines
47+
resp, err := s.client.Do(ctx, req, &machines)
48+
if err != nil {
49+
return nil, resp, err
50+
}
51+
52+
return machines, resp, nil
53+
}
54+
55+
// ListCodespaceMachineTypes lists the machine types a codespace can transition to use.
56+
//
57+
// GitHub API docs: https://docs.github.com/rest/codespaces/machines#list-machine-types-for-a-codespace
58+
//
59+
//meta:operation GET /user/codespaces/{codespace_name}/machines
60+
func (s *CodespacesService) ListCodespaceMachineTypes(ctx context.Context, codespaceName string) (*CodespacesMachines, *Response, error) {
61+
u := fmt.Sprintf("user/codespaces/%v/machines", codespaceName)
62+
req, err := s.client.NewRequest("GET", u, nil)
63+
if err != nil {
64+
return nil, nil, err
65+
}
66+
67+
var machines *CodespacesMachines
68+
resp, err := s.client.Do(ctx, req, &machines)
69+
if err != nil {
70+
return nil, resp, err
71+
}
72+
73+
return machines, resp, nil
74+
}

github/codespaces_machines_test.go

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
// Copyright 2025 The go-github AUTHORS. All rights reserved.
2+
//
3+
// Use of this source code is governed by a BSD-style
4+
// license that can be found in the LICENSE file.
5+
6+
package github
7+
8+
import (
9+
"fmt"
10+
"net/http"
11+
"testing"
12+
13+
"github.com/google/go-cmp/cmp"
14+
)
15+
16+
func TestCodespacesService_ListRepositoryMachineTypes(t *testing.T) {
17+
t.Parallel()
18+
client, mux, _ := setup(t)
19+
20+
mux.HandleFunc("/repos/owner/repo/codespaces/machines", func(w http.ResponseWriter, r *http.Request) {
21+
testMethod(t, r, "GET")
22+
testFormValues(t, r, values{
23+
"ref": "main",
24+
"location": "WestUs2",
25+
"client_ip": "1.2.3.4",
26+
})
27+
fmt.Fprint(w, `{
28+
"total_count": 1,
29+
"machines": [
30+
{
31+
"name": "standardLinux",
32+
"display_name": "4 cores, 8 GB RAM, 64 GB storage",
33+
"operating_system": "linux",
34+
"storage_in_bytes": 68719476736,
35+
"memory_in_bytes": 17179869184,
36+
"cpus": 4,
37+
"prebuild_availability": "ready"
38+
}
39+
]
40+
}`)
41+
})
42+
43+
ctx := t.Context()
44+
opts := &ListRepoMachineTypesOptions{
45+
Ref: Ptr("main"),
46+
Location: Ptr("WestUs2"),
47+
ClientIP: Ptr("1.2.3.4"),
48+
}
49+
50+
got, _, err := client.Codespaces.ListRepositoryMachineTypes(
51+
ctx,
52+
"owner",
53+
"repo",
54+
opts,
55+
)
56+
if err != nil {
57+
t.Fatalf("Codespaces.ListRepositoryMachineTypes returned error: %v", err)
58+
}
59+
60+
want := &CodespacesMachines{
61+
TotalCount: 1,
62+
Machines: []*CodespacesMachine{
63+
{
64+
Name: Ptr("standardLinux"),
65+
DisplayName: Ptr("4 cores, 8 GB RAM, 64 GB storage"),
66+
OperatingSystem: Ptr("linux"),
67+
StorageInBytes: Ptr(int64(68719476736)),
68+
MemoryInBytes: Ptr(int64(17179869184)),
69+
CPUs: Ptr(4),
70+
PrebuildAvailability: Ptr("ready"),
71+
},
72+
},
73+
}
74+
75+
if !cmp.Equal(got, want) {
76+
t.Errorf("Codespaces.ListRepositoryMachineTypes returned %+v, want %+v", got, want)
77+
}
78+
79+
const methodName = "ListRepositoryMachineTypes"
80+
testBadOptions(t, methodName, func() error {
81+
_, _, err := client.Codespaces.ListRepositoryMachineTypes(ctx, "\n", "/n", opts)
82+
return err
83+
})
84+
testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
85+
got, resp, err := client.Codespaces.ListRepositoryMachineTypes(ctx, "/n", "/n", opts)
86+
if got != nil {
87+
t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
88+
}
89+
return resp, err
90+
})
91+
}
92+
93+
func TestCodespacesService_ListCodespaceMachineTypes(t *testing.T) {
94+
t.Parallel()
95+
client, mux, _ := setup(t)
96+
97+
mux.HandleFunc("/user/codespaces/codespace_1/machines", func(w http.ResponseWriter, r *http.Request) {
98+
testMethod(t, r, "GET")
99+
100+
fmt.Fprint(w, `{
101+
"total_count": 1,
102+
"machines": [
103+
{
104+
"name": "standardLinux",
105+
"display_name": "4 cores, 8 GB RAM, 64 GB storage",
106+
"operating_system": "linux",
107+
"storage_in_bytes": 68719476736,
108+
"memory_in_bytes": 17179869184,
109+
"cpus": 4,
110+
"prebuild_availability": "ready"
111+
}
112+
]
113+
}`)
114+
})
115+
116+
ctx := t.Context()
117+
got, _, err := client.Codespaces.ListCodespaceMachineTypes(ctx, "codespace_1")
118+
if err != nil {
119+
t.Fatalf("Codespaces.ListCodespaceMachineTypes returned error: %v", err)
120+
}
121+
122+
want := &CodespacesMachines{
123+
TotalCount: 1,
124+
Machines: []*CodespacesMachine{
125+
{
126+
Name: Ptr("standardLinux"),
127+
DisplayName: Ptr("4 cores, 8 GB RAM, 64 GB storage"),
128+
OperatingSystem: Ptr("linux"),
129+
StorageInBytes: Ptr(int64(68719476736)),
130+
MemoryInBytes: Ptr(int64(17179869184)),
131+
CPUs: Ptr(4),
132+
PrebuildAvailability: Ptr("ready"),
133+
},
134+
},
135+
}
136+
137+
if !cmp.Equal(got, want) {
138+
t.Errorf("Codespaces.ListCodespaceMachineTypes returned %+v, want %+v", got, want)
139+
}
140+
141+
const methodName = "ListCodespaceMachineTypes"
142+
testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
143+
got, resp, err := client.Codespaces.ListCodespaceMachineTypes(ctx, "/n")
144+
if got != nil {
145+
t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
146+
}
147+
return resp, err
148+
})
149+
}

github/github-accessors.go

Lines changed: 24 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

github/github-accessors_test.go

Lines changed: 33 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)