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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions github/codespaces_machines.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Copyright 2025 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package github

import (
"context"
"fmt"
)

// CodespacesMachines represent a list of machines.
type CodespacesMachines struct {
TotalCount int64 `json:"total_count"`
Machines []*CodespacesMachine `json:"machines"`
}

// ListRepoMachineTypesOptions represent options for ListMachineTypesForRepository.
type ListRepoMachineTypesOptions struct {
// Ref represent the branch or commit to check for prebuild availability and devcontainer restrictions.
Ref *string `url:"ref,omitempty"`
// Location represent the location to check for available machines. Assigned by IP if not provided.
Location *string `url:"location,omitempty"`
// ClientIP represent the IP for location auto-detection when proxying a request
ClientIP *string `url:"client_ip,omitempty"`
}

// ListRepositoryMachineTypes lists the machine types available for a given repository based on its configuration.
//
// GitHub API docs: https://docs.github.com/rest/codespaces/machines#list-available-machine-types-for-a-repository
//
//meta:operation GET /repos/{owner}/{repo}/codespaces/machines
func (s *CodespacesService) ListRepositoryMachineTypes(ctx context.Context, owner, repo string, opts *ListRepoMachineTypesOptions) (*CodespacesMachines, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/codespaces/machines", owner, repo)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}

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

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

return machines, resp, nil
}

// ListCodespaceMachineTypes lists the machine types a codespace can transition to use.
//
// GitHub API docs: https://docs.github.com/rest/codespaces/machines#list-machine-types-for-a-codespace
//
//meta:operation GET /user/codespaces/{codespace_name}/machines
func (s *CodespacesService) ListCodespaceMachineTypes(ctx context.Context, codespaceName string) (*CodespacesMachines, *Response, error) {
u := fmt.Sprintf("user/codespaces/%v/machines", codespaceName)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}

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

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

package github

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

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

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

mux.HandleFunc("/repos/owner/repo/codespaces/machines", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{
"ref": "main",
"location": "WestUs2",
"client_ip": "1.2.3.4",
})
fmt.Fprint(w, `{
"total_count": 1,
"machines": [
{
"name": "standardLinux",
"display_name": "4 cores, 8 GB RAM, 64 GB storage",
"operating_system": "linux",
"storage_in_bytes": 68719476736,
"memory_in_bytes": 17179869184,
"cpus": 4,
"prebuild_availability": "ready"
}
]
}`)
})

ctx := t.Context()
opts := &ListRepoMachineTypesOptions{
Ref: Ptr("main"),
Location: Ptr("WestUs2"),
ClientIP: Ptr("1.2.3.4"),
}

got, _, err := client.Codespaces.ListRepositoryMachineTypes(
ctx,
"owner",
"repo",
opts,
)
if err != nil {
t.Fatalf("Codespaces.ListRepositoryMachineTypes returned error: %v", err)
}

want := &CodespacesMachines{
TotalCount: 1,
Machines: []*CodespacesMachine{
{
Name: Ptr("standardLinux"),
DisplayName: Ptr("4 cores, 8 GB RAM, 64 GB storage"),
OperatingSystem: Ptr("linux"),
StorageInBytes: Ptr(int64(68719476736)),
MemoryInBytes: Ptr(int64(17179869184)),
CPUs: Ptr(4),
PrebuildAvailability: Ptr("ready"),
},
},
}

if !cmp.Equal(got, want) {
t.Errorf("Codespaces.ListRepositoryMachineTypes returned %+v, want %+v", got, want)
}

const methodName = "ListRepositoryMachineTypes"
testBadOptions(t, methodName, func() error {
_, _, err := client.Codespaces.ListRepositoryMachineTypes(ctx, "\n", "/n", opts)
return err
})
testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
got, resp, err := client.Codespaces.ListRepositoryMachineTypes(ctx, "/n", "/n", opts)
if got != nil {
t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
}
return resp, err
})
}

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

mux.HandleFunc("/user/codespaces/codespace_1/machines", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")

fmt.Fprint(w, `{
"total_count": 1,
"machines": [
{
"name": "standardLinux",
"display_name": "4 cores, 8 GB RAM, 64 GB storage",
"operating_system": "linux",
"storage_in_bytes": 68719476736,
"memory_in_bytes": 17179869184,
"cpus": 4,
"prebuild_availability": "ready"
}
]
}`)
})

ctx := t.Context()
got, _, err := client.Codespaces.ListCodespaceMachineTypes(ctx, "codespace_1")
if err != nil {
t.Fatalf("Codespaces.ListCodespaceMachineTypes returned error: %v", err)
}

want := &CodespacesMachines{
TotalCount: 1,
Machines: []*CodespacesMachine{
{
Name: Ptr("standardLinux"),
DisplayName: Ptr("4 cores, 8 GB RAM, 64 GB storage"),
OperatingSystem: Ptr("linux"),
StorageInBytes: Ptr(int64(68719476736)),
MemoryInBytes: Ptr(int64(17179869184)),
CPUs: Ptr(4),
PrebuildAvailability: Ptr("ready"),
},
},
}

if !cmp.Equal(got, want) {
t.Errorf("Codespaces.ListCodespaceMachineTypes returned %+v, want %+v", got, want)
}

const methodName = "ListCodespaceMachineTypes"
testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
got, resp, err := client.Codespaces.ListCodespaceMachineTypes(ctx, "/n")
if got != nil {
t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
}
return resp, err
})
}
24 changes: 24 additions & 0 deletions github/github-accessors.go

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

33 changes: 33 additions & 0 deletions github/github-accessors_test.go

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

Loading