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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 118 additions & 0 deletions github/actions_oidc.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,121 @@ func (s *ActionsService) setOIDCSubjectClaimCustomTemplate(ctx context.Context,

return s.client.Do(req, nil)
}

// InclusionSource represents whether the custom oidc property claim was defined at the organization or enterprise level.
type InclusionSource string

// InclusionSource constants represent whether the inclusion was defined at the organization or enterprise level.
const (
InclusionSourceEnterprise InclusionSource = "enterprise"
InclusionSourceOrganization InclusionSource = "organization"
)

// OIDCCustomPropertyClaim represents an OIDC custom property claim for GitHub Actions.
type OIDCCustomPropertyClaim struct {
CustomPropertyName string `json:"custom_property_name"`
}

// OIDCCustomPropertyClaimResponse represents the OIDC custom property claim along with the inclusion source (enterprise or organization) for GitHub Actions.
type OIDCCustomPropertyClaimResponse struct {
OIDCCustomPropertyClaim
InclusionSource InclusionSource `json:"inclusion_source"`
}
Comment thread
sswane marked this conversation as resolved.

// ListEnterpriseOIDCCustomPropertyClaims lists the custom property claims in oidc for enterprise actions.
//
// GitHub API docs: https://docs.github.com/rest/actions/oidc?apiVersion=2022-11-28#list-oidc-custom-property-inclusions-for-an-enterprise
//
//meta:operation GET /enterprises/{enterprise}/actions/oidc/customization/properties/repo
func (s *ActionsService) ListEnterpriseOIDCCustomPropertyClaims(ctx context.Context, enterprise string) ([]*OIDCCustomPropertyClaimResponse, *Response, error) {
u := fmt.Sprintf("enterprises/%v/actions/oidc/customization/properties/repo", enterprise)
return s.listOIDCCustomPropertyClaims(ctx, u)
}

// ListOrgOIDCCustomPropertyClaims lists the custom property claims in oidc for organization actions.
//
// GitHub API docs: https://docs.github.com/rest/actions/oidc?apiVersion=2022-11-28#list-oidc-custom-property-inclusions-for-an-organization
//
//meta:operation GET /orgs/{org}/actions/oidc/customization/properties/repo
func (s *ActionsService) ListOrgOIDCCustomPropertyClaims(ctx context.Context, org string) ([]*OIDCCustomPropertyClaimResponse, *Response, error) {
u := fmt.Sprintf("orgs/%v/actions/oidc/customization/properties/repo", org)
return s.listOIDCCustomPropertyClaims(ctx, u)
}

func (s *ActionsService) listOIDCCustomPropertyClaims(ctx context.Context, url string) ([]*OIDCCustomPropertyClaimResponse, *Response, error) {
req, err := s.client.NewRequest(ctx, "GET", url, nil)
if err != nil {
return nil, nil, err
}

var props []*OIDCCustomPropertyClaimResponse
resp, err := s.client.Do(req, &props)
if err != nil {
return nil, resp, err
}

return props, resp, nil
}

// SetEnterpriseOIDCCustomPropertyClaim sets a new custom property claim in oidc for enterprise actions.
//
// GitHub API docs: https://docs.github.com/rest/actions/oidc?apiVersion=2022-11-28#create-an-oidc-custom-property-inclusion-for-an-enterprise
//
//meta:operation POST /enterprises/{enterprise}/actions/oidc/customization/properties/repo
func (s *ActionsService) SetEnterpriseOIDCCustomPropertyClaim(ctx context.Context, enterprise string, body OIDCCustomPropertyClaim) (*OIDCCustomPropertyClaim, *Response, error) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't use OIDCCustomPropertyClaim here. Because this endpoint only accepts custom_property_name in body parameter. so let's introduce a new request struct for this.

Image

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah right. just added a new type OIDCCustomPropertyClaimResponse and updated the List/GET methods to use that instead.

u := fmt.Sprintf("enterprises/%v/actions/oidc/customization/properties/repo", enterprise)
return s.setOIDCCustomPropertyClaim(ctx, u, body)
}

// SetOrgOIDCCustomPropertyClaim sets a new custom property claim in oidc for organization actions.
//
// GitHub API docs: https://docs.github.com/rest/actions/oidc?apiVersion=2022-11-28#create-an-oidc-custom-property-inclusion-for-an-organization
//
//meta:operation POST /orgs/{org}/actions/oidc/customization/properties/repo
func (s *ActionsService) SetOrgOIDCCustomPropertyClaim(ctx context.Context, org string, body OIDCCustomPropertyClaim) (*OIDCCustomPropertyClaim, *Response, error) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here.
Let's introduce a new request struct for this.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ended up making OIDCCustomPropertyClaimResponse and updating the List/GET methods to use that but I can instead switch it back & create the Request one if you prefer.

u := fmt.Sprintf("orgs/%v/actions/oidc/customization/properties/repo", org)
return s.setOIDCCustomPropertyClaim(ctx, u, body)
}

func (s *ActionsService) setOIDCCustomPropertyClaim(ctx context.Context, url string, body OIDCCustomPropertyClaim) (*OIDCCustomPropertyClaim, *Response, error) {
req, err := s.client.NewRequest(ctx, "POST", url, body)
if err != nil {
return nil, nil, err
}

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

// DeleteEnterpriseOIDCCustomPropertyClaim deletes a custom property claim in oidc for enterprise actions.
//
// GitHub API docs: https://docs.github.com/rest/actions/oidc?apiVersion=2022-11-28#delete-an-oidc-custom-property-inclusion-for-an-enterprise
//
//meta:operation DELETE /enterprises/{enterprise}/actions/oidc/customization/properties/repo/{custom_property_name}
func (s *ActionsService) DeleteEnterpriseOIDCCustomPropertyClaim(ctx context.Context, enterprise, customProperty string) (*Response, error) {
u := fmt.Sprintf("enterprises/%v/actions/oidc/customization/properties/repo/%v", enterprise, customProperty)
return s.deleteOIDCCustomPropertyClaim(ctx, u)
}

// DeleteOrgOIDCCustomPropertyClaim deletes a custom property claim in oidc for organization actions.
//
// GitHub API docs: https://docs.github.com/rest/actions/oidc?apiVersion=2022-11-28#delete-an-oidc-custom-property-inclusion-for-an-organization
//
//meta:operation DELETE /orgs/{org}/actions/oidc/customization/properties/repo/{custom_property_name}
func (s *ActionsService) DeleteOrgOIDCCustomPropertyClaim(ctx context.Context, enterprise, customProperty string) (*Response, error) {
u := fmt.Sprintf("orgs/%v/actions/oidc/customization/properties/repo/%v", enterprise, customProperty)
return s.deleteOIDCCustomPropertyClaim(ctx, u)
}

func (s *ActionsService) deleteOIDCCustomPropertyClaim(ctx context.Context, url string) (*Response, error) {
req, err := s.client.NewRequest(ctx, "DELETE", url, nil)
if err != nil {
return nil, err
}

return s.client.Do(req, nil)
}
214 changes: 214 additions & 0 deletions github/actions_oidc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,3 +182,217 @@ func TestActionsService_SetRepoOIDCSubjectClaimCustomTemplateToDefault(t *testin
return client.Actions.SetRepoOIDCSubjectClaimCustomTemplate(ctx, "o", "r", input)
})
}

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

mux.HandleFunc("/enterprises/e/actions/oidc/customization/properties/repo", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `[{"custom_property_name": "environment","inclusion_source": "enterprise"},{"custom_property_name": "lane","inclusion_source": "enterprise"}]`)
})

ctx := t.Context()
claims, _, err := client.Actions.ListEnterpriseOIDCCustomPropertyClaims(ctx, "e")
if err != nil {
t.Errorf("Actions.ListEnterpriseOIDCCustomPropertyClaims returned error: %v", err)
}

want := []*OIDCCustomPropertyClaimResponse{
{OIDCCustomPropertyClaim: OIDCCustomPropertyClaim{"environment"}, InclusionSource: InclusionSourceEnterprise},
{OIDCCustomPropertyClaim: OIDCCustomPropertyClaim{"lane"}, InclusionSource: InclusionSourceEnterprise},
}

if !cmp.Equal(claims, want) {
t.Errorf("Actions.ListEnterpriseOIDCCustomPropertyClaims returned %+v, want %+v", claims, want)
}

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

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

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

mux.HandleFunc("/orgs/o/actions/oidc/customization/properties/repo", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `[{"custom_property_name": "environment","inclusion_source": "organization"},{"custom_property_name": "lane","inclusion_source": "organization"}]`)
})

ctx := t.Context()
claims, _, err := client.Actions.ListOrgOIDCCustomPropertyClaims(ctx, "o")
if err != nil {
t.Errorf("Actions.ListOrgOIDCCustomPropertyClaims returned error: %v", err)
}

want := []*OIDCCustomPropertyClaimResponse{
{OIDCCustomPropertyClaim: OIDCCustomPropertyClaim{"environment"}, InclusionSource: InclusionSourceOrganization},
{OIDCCustomPropertyClaim: OIDCCustomPropertyClaim{"lane"}, InclusionSource: InclusionSourceOrganization},
}

if !cmp.Equal(claims, want) {
t.Errorf("Actions.ListOrgOIDCCustomPropertyClaims returned %+v, want %+v", claims, want)
}

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

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

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

input := OIDCCustomPropertyClaim{
CustomPropertyName: "environment",
}

mux.HandleFunc("/enterprises/e/actions/oidc/customization/properties/repo", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "POST")
testHeader(t, r, "Content-Type", "application/json")
testJSONBody(t, r, input)
w.WriteHeader(http.StatusCreated)
fmt.Fprint(w, `{"custom_property_name": "environment"}`)
})

ctx := t.Context()
property, _, err := client.Actions.SetEnterpriseOIDCCustomPropertyClaim(ctx, "e", input)
if err != nil {
t.Errorf("Actions.SetEnterpriseOIDCCustomPropertyClaim returned error: %v", err)
}

want := &OIDCCustomPropertyClaim{CustomPropertyName: "environment"}
if !cmp.Equal(property, want) {
t.Errorf("Actions.SetEnterpriseOIDCCustomPropertyClaim returned %+v, want %+v", property, want)
}

const methodName = "SetEnterpriseOIDCCustomPropertyClaim"

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

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

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

input := OIDCCustomPropertyClaim{
CustomPropertyName: "environment",
}

mux.HandleFunc("/orgs/o/actions/oidc/customization/properties/repo", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "POST")
testHeader(t, r, "Content-Type", "application/json")
testJSONBody(t, r, input)
w.WriteHeader(http.StatusCreated)
fmt.Fprint(w, `{"custom_property_name": "environment"}`)
})

ctx := t.Context()
property, _, err := client.Actions.SetOrgOIDCCustomPropertyClaim(ctx, "o", input)
if err != nil {
t.Errorf("Actions.SetOrgOIDCCustomPropertyClaim returned error: %v", err)
}

want := &OIDCCustomPropertyClaim{CustomPropertyName: "environment"}
if !cmp.Equal(property, want) {
t.Errorf("Actions.SetOrgOIDCCustomPropertyClaim returned %+v, want %+v", property, want)
}

const methodName = "SetOrgOIDCCustomPropertyClaim"

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

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

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

mux.HandleFunc("/enterprises/e/actions/oidc/customization/properties/repo/environment", func(_ http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
})

ctx := t.Context()
_, err := client.Actions.DeleteEnterpriseOIDCCustomPropertyClaim(ctx, "e", "environment")
if err != nil {
t.Errorf("Actions.DeleteEnterpriseOIDCCustomPropertyClaim return error: %v", err)
}

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

testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
return client.Actions.DeleteEnterpriseOIDCCustomPropertyClaim(ctx, "e", "r")
})
}

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

mux.HandleFunc("/orgs/o/actions/oidc/customization/properties/repo/environment", func(_ http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
})

ctx := t.Context()
_, err := client.Actions.DeleteOrgOIDCCustomPropertyClaim(ctx, "o", "environment")
if err != nil {
t.Errorf("Actions.DeleteOrgOIDCCustomPropertyClaim return error: %v", err)
}

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

testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
return client.Actions.DeleteOrgOIDCCustomPropertyClaim(ctx, "o", "r")
})
}
16 changes: 16 additions & 0 deletions github/github-accessors.go

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

16 changes: 16 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