mirror of
https://github.com/google/go-github.git
synced 2026-10-29 00:44:52 +08:00
318 lines
11 KiB
Go
318 lines
11 KiB
Go
// Copyright 2023 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"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"strconv"
|
|
)
|
|
|
|
// PropertyValueType represents the type of a custom property value.
|
|
type PropertyValueType string
|
|
|
|
// Valid values for CustomProperty.ValueType.
|
|
const (
|
|
PropertyValueTypeString PropertyValueType = "string"
|
|
PropertyValueTypeSingleSelect PropertyValueType = "single_select"
|
|
PropertyValueTypeMultiSelect PropertyValueType = "multi_select"
|
|
PropertyValueTypeTrueFalse PropertyValueType = "true_false"
|
|
PropertyValueTypeURL PropertyValueType = "url"
|
|
)
|
|
|
|
// CustomProperty represents an organization custom property object.
|
|
type CustomProperty struct {
|
|
// PropertyName is required for most endpoints except when calling CreateOrUpdateCustomProperty;
|
|
// where this is sent in the path and thus can be omitted.
|
|
PropertyName *string `json:"property_name,omitempty"`
|
|
// The URL that can be used to fetch, update, or delete info about this property via the API.
|
|
URL *string `json:"url,omitempty"`
|
|
// SourceType is the source type of the property where it has been created. Can be one of: organization, enterprise.
|
|
SourceType *string `json:"source_type,omitempty"`
|
|
// The type of the value for the property. Can be one of: string, single_select, multi_select, true_false, url.
|
|
ValueType PropertyValueType `json:"value_type"`
|
|
// Whether the property is required.
|
|
Required *bool `json:"required,omitempty"`
|
|
// Whether setting property values is mandatory.
|
|
RequireExplicitValues *bool `json:"require_explicit_values,omitempty"`
|
|
// Default value of the property.
|
|
DefaultValue any `json:"default_value,omitempty"`
|
|
// Short description of the property.
|
|
Description *string `json:"description,omitempty"`
|
|
// An ordered list of the allowed values of the property. The property can have up to 200
|
|
// allowed values.
|
|
AllowedValues []string `json:"allowed_values,omitempty"`
|
|
// Who can edit the values of the property. Can be one of: org_actors, org_and_repo_actors, nil (null).
|
|
ValuesEditableBy *string `json:"values_editable_by,omitempty"`
|
|
}
|
|
|
|
// DefaultValueString returns the DefaultValue as a string if the ValueType is string or single_select or url.
|
|
func (cp CustomProperty) DefaultValueString() (string, bool) {
|
|
switch cp.ValueType {
|
|
case PropertyValueTypeString, PropertyValueTypeSingleSelect, PropertyValueTypeURL:
|
|
s, ok := cp.DefaultValue.(string)
|
|
return s, ok
|
|
default:
|
|
return "", false
|
|
}
|
|
}
|
|
|
|
// DefaultValueStrings returns the DefaultValue as a slice of string if the ValueType is multi_select.
|
|
func (cp CustomProperty) DefaultValueStrings() ([]string, bool) {
|
|
switch cp.ValueType {
|
|
case PropertyValueTypeMultiSelect:
|
|
switch v := cp.DefaultValue.(type) {
|
|
case []string:
|
|
return v, true
|
|
case []any:
|
|
vals := make([]string, len(v))
|
|
for i, item := range v {
|
|
s, ok := item.(string)
|
|
if !ok {
|
|
return nil, false
|
|
}
|
|
vals[i] = s
|
|
}
|
|
return vals, true
|
|
default:
|
|
return nil, false
|
|
}
|
|
default:
|
|
return nil, false
|
|
}
|
|
}
|
|
|
|
// DefaultValueBool returns the DefaultValue as a string if the ValueType is true_false.
|
|
func (cp CustomProperty) DefaultValueBool() (bool, bool) {
|
|
switch cp.ValueType {
|
|
case PropertyValueTypeTrueFalse:
|
|
if s, ok := cp.DefaultValue.(string); ok {
|
|
b, err := strconv.ParseBool(s)
|
|
return b, err == nil
|
|
}
|
|
return false, false
|
|
default:
|
|
return false, false
|
|
}
|
|
}
|
|
|
|
// RepoCustomPropertyValue represents a repository custom property value.
|
|
type RepoCustomPropertyValue struct {
|
|
RepositoryID int64 `json:"repository_id"`
|
|
RepositoryName string `json:"repository_name"`
|
|
RepositoryFullName string `json:"repository_full_name"`
|
|
Properties []*CustomPropertyValue `json:"properties"`
|
|
}
|
|
|
|
// CustomPropertyValue represents a custom property value.
|
|
type CustomPropertyValue struct {
|
|
PropertyName string `json:"property_name"`
|
|
Value any `json:"value"`
|
|
}
|
|
|
|
// ListCustomPropertyValuesOptions specifies the optional parameters to the
|
|
// OrganizationsService.ListCustomPropertyValues method.
|
|
type ListCustomPropertyValuesOptions struct {
|
|
RepositoryQuery string `url:"repository_query,omitempty"`
|
|
ListOptions
|
|
}
|
|
|
|
// UnmarshalJSON implements the json.Unmarshaler interface.
|
|
// This helps us handle the fact that Value can be either a string, []string, or nil.
|
|
func (cpv *CustomPropertyValue) UnmarshalJSON(data []byte) error {
|
|
type aliasCustomPropertyValue CustomPropertyValue
|
|
aux := &struct {
|
|
*aliasCustomPropertyValue
|
|
}{
|
|
aliasCustomPropertyValue: (*aliasCustomPropertyValue)(cpv),
|
|
}
|
|
if err := json.Unmarshal(data, &aux); err != nil {
|
|
return err
|
|
}
|
|
|
|
switch v := aux.Value.(type) {
|
|
case nil:
|
|
cpv.Value = nil
|
|
case string:
|
|
cpv.Value = v
|
|
case []any:
|
|
strSlice := make([]string, len(v))
|
|
for i, item := range v {
|
|
str, ok := item.(string)
|
|
if !ok {
|
|
return errors.New("non-string value in string array")
|
|
}
|
|
strSlice[i] = str
|
|
}
|
|
cpv.Value = strSlice
|
|
default:
|
|
return fmt.Errorf("unexpected value type: %T", v)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GetAllCustomProperties gets all custom properties that are defined for the specified organization.
|
|
//
|
|
// GitHub API docs: https://docs.github.com/rest/orgs/custom-properties?apiVersion=2022-11-28#get-all-custom-properties-for-an-organization
|
|
//
|
|
//meta:operation GET /orgs/{org}/properties/schema
|
|
func (s *OrganizationsService) GetAllCustomProperties(ctx context.Context, org string) ([]*CustomProperty, *Response, error) {
|
|
u := fmt.Sprintf("orgs/%v/properties/schema", org)
|
|
|
|
req, err := s.client.NewRequest(ctx, "GET", u, nil)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
var customProperties []*CustomProperty
|
|
resp, err := s.client.Do(req, &customProperties)
|
|
if err != nil {
|
|
return nil, resp, err
|
|
}
|
|
|
|
return customProperties, resp, nil
|
|
}
|
|
|
|
// CreateOrUpdateCustomProperties creates new or updates existing custom properties that are defined for the specified organization.
|
|
//
|
|
// GitHub API docs: https://docs.github.com/rest/orgs/custom-properties?apiVersion=2022-11-28#create-or-update-custom-properties-for-an-organization
|
|
//
|
|
//meta:operation PATCH /orgs/{org}/properties/schema
|
|
func (s *OrganizationsService) CreateOrUpdateCustomProperties(ctx context.Context, org string, properties []*CustomProperty) ([]*CustomProperty, *Response, error) {
|
|
u := fmt.Sprintf("orgs/%v/properties/schema", org)
|
|
|
|
params := struct {
|
|
Properties []*CustomProperty `json:"properties"`
|
|
}{
|
|
Properties: properties,
|
|
}
|
|
|
|
req, err := s.client.NewRequest(ctx, "PATCH", u, params)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
var customProperties []*CustomProperty
|
|
resp, err := s.client.Do(req, &customProperties)
|
|
if err != nil {
|
|
return nil, resp, err
|
|
}
|
|
|
|
return customProperties, resp, nil
|
|
}
|
|
|
|
// GetCustomProperty gets a custom property that is defined for the specified organization.
|
|
//
|
|
// GitHub API docs: https://docs.github.com/rest/orgs/custom-properties?apiVersion=2022-11-28#get-a-custom-property-for-an-organization
|
|
//
|
|
//meta:operation GET /orgs/{org}/properties/schema/{custom_property_name}
|
|
func (s *OrganizationsService) GetCustomProperty(ctx context.Context, org, name string) (*CustomProperty, *Response, error) {
|
|
u := fmt.Sprintf("orgs/%v/properties/schema/%v", org, name)
|
|
|
|
req, err := s.client.NewRequest(ctx, "GET", u, nil)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
var customProperty *CustomProperty
|
|
resp, err := s.client.Do(req, &customProperty)
|
|
if err != nil {
|
|
return nil, resp, err
|
|
}
|
|
|
|
return customProperty, resp, nil
|
|
}
|
|
|
|
// CreateOrUpdateCustomProperty creates a new or updates an existing custom property that is defined for the specified organization.
|
|
//
|
|
// GitHub API docs: https://docs.github.com/rest/orgs/custom-properties?apiVersion=2022-11-28#create-or-update-a-custom-property-for-an-organization
|
|
//
|
|
//meta:operation PUT /orgs/{org}/properties/schema/{custom_property_name}
|
|
func (s *OrganizationsService) CreateOrUpdateCustomProperty(ctx context.Context, org, customPropertyName string, body *CustomProperty) (*CustomProperty, *Response, error) {
|
|
u := fmt.Sprintf("orgs/%v/properties/schema/%v", org, customPropertyName)
|
|
|
|
req, err := s.client.NewRequest(ctx, "PUT", u, body)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
var customProperty *CustomProperty
|
|
resp, err := s.client.Do(req, &customProperty)
|
|
if err != nil {
|
|
return nil, resp, err
|
|
}
|
|
|
|
return customProperty, resp, nil
|
|
}
|
|
|
|
// RemoveCustomProperty removes a custom property that is defined for the specified organization.
|
|
//
|
|
// GitHub API docs: https://docs.github.com/rest/orgs/custom-properties?apiVersion=2022-11-28#remove-a-custom-property-for-an-organization
|
|
//
|
|
//meta:operation DELETE /orgs/{org}/properties/schema/{custom_property_name}
|
|
func (s *OrganizationsService) RemoveCustomProperty(ctx context.Context, org, customPropertyName string) (*Response, error) {
|
|
u := fmt.Sprintf("orgs/%v/properties/schema/%v", org, customPropertyName)
|
|
|
|
req, err := s.client.NewRequest(ctx, "DELETE", u, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return s.client.Do(req, nil)
|
|
}
|
|
|
|
// ListCustomPropertyValues lists all custom property values for repositories in the specified organization.
|
|
//
|
|
// GitHub API docs: https://docs.github.com/rest/orgs/custom-properties?apiVersion=2022-11-28#list-custom-property-values-for-organization-repositories
|
|
//
|
|
//meta:operation GET /orgs/{org}/properties/values
|
|
func (s *OrganizationsService) ListCustomPropertyValues(ctx context.Context, org string, opts *ListCustomPropertyValuesOptions) ([]*RepoCustomPropertyValue, *Response, error) {
|
|
u := fmt.Sprintf("orgs/%v/properties/values", org)
|
|
u, err := addOptions(u, opts)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
req, err := s.client.NewRequest(ctx, "GET", u, nil)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
var repoCustomPropertyValues []*RepoCustomPropertyValue
|
|
resp, err := s.client.Do(req, &repoCustomPropertyValues)
|
|
if err != nil {
|
|
return nil, resp, err
|
|
}
|
|
|
|
return repoCustomPropertyValues, resp, nil
|
|
}
|
|
|
|
// CreateOrUpdateRepoCustomPropertyValues creates new or updates existing custom property values across multiple repositories for the specified organization.
|
|
//
|
|
// GitHub API docs: https://docs.github.com/rest/orgs/custom-properties?apiVersion=2022-11-28#create-or-update-custom-property-values-for-organization-repositories
|
|
//
|
|
//meta:operation PATCH /orgs/{org}/properties/values
|
|
func (s *OrganizationsService) CreateOrUpdateRepoCustomPropertyValues(ctx context.Context, org string, repoNames []string, properties []*CustomPropertyValue) (*Response, error) {
|
|
u := fmt.Sprintf("orgs/%v/properties/values", org)
|
|
|
|
params := struct {
|
|
RepositoryNames []string `json:"repository_names"`
|
|
Properties []*CustomPropertyValue `json:"properties"`
|
|
}{
|
|
RepositoryNames: repoNames,
|
|
Properties: properties,
|
|
}
|
|
|
|
req, err := s.client.NewRequest(ctx, "PATCH", u, params)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return s.client.Do(req, nil)
|
|
}
|