feat!: Add support for project items CRUD and project fields read operations (#3793)

This commit is contained in:
Jonathan authored and GitHub committed 2025-11-03 07:07:06 -05:00
1 parent e7abb9f86a
commit 2b239f2dc6
6 files changed
+1602 -263

No files matched your search

+12 -9
View File
@@ -1150,15 +1150,18 @@ type FieldValue struct {
// ProjectV2Item represents an item belonging to a project.
type ProjectV2Item struct {
ID *int64 `json:"id,omitempty"`
NodeID *string `json:"node_id,omitempty"`
ProjectNodeID *string `json:"project_node_id,omitempty"`
ContentNodeID *string `json:"content_node_id,omitempty"`
ContentType *string `json:"content_type,omitempty"`
Creator *User `json:"creator,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
ArchivedAt *Timestamp `json:"archived_at,omitempty"`
ID *int64 `json:"id,omitempty"`
NodeID *string `json:"node_id,omitempty"`
ProjectNodeID *string `json:"project_node_id,omitempty"`
ContentNodeID *string `json:"content_node_id,omitempty"`
ProjectURL *string `json:"project_url,omitempty"`
ContentType *string `json:"content_type,omitempty"`
Creator *User `json:"creator,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
ArchivedAt *Timestamp `json:"archived_at,omitempty"`
ItemURL *string `json:"item_url,omitempty"`
Fields []*ProjectV2Field `json:"fields,omitempty"`
}
// PublicEvent is triggered when a private repository is open sourced.
+176
View File
@@ -14078,6 +14078,38 @@ func (l *ListOrganizations) GetTotalCount() int {
return *l.TotalCount
}
// GetQuery returns the Query field if it's non-nil, zero value otherwise.
func (l *ListProjectsOptions) GetQuery() string {
if l == nil || l.Query == nil {
return ""
}
return *l.Query
}
// GetAfter returns the After field if it's non-nil, zero value otherwise.
func (l *ListProjectsPaginationOptions) GetAfter() string {
if l == nil || l.After == nil {
return ""
}
return *l.After
}
// GetBefore returns the Before field if it's non-nil, zero value otherwise.
func (l *ListProjectsPaginationOptions) GetBefore() string {
if l == nil || l.Before == nil {
return ""
}
return *l.Before
}
// GetPerPage returns the PerPage field if it's non-nil, zero value otherwise.
func (l *ListProjectsPaginationOptions) GetPerPage() int {
if l == nil || l.PerPage == nil {
return 0
}
return *l.PerPage
}
// GetTotalCount returns the TotalCount field if it's non-nil, zero value otherwise.
func (l *ListRepositories) GetTotalCount() int {
if l == nil || l.TotalCount == nil {
@@ -19118,6 +19150,14 @@ func (p *ProjectV2Event) GetSender() *User {
return p.Sender
}
// GetConfiguration returns the Configuration field.
func (p *ProjectV2Field) GetConfiguration() *ProjectV2FieldConfiguration {
if p == nil {
return nil
}
return p.Configuration
}
// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
func (p *ProjectV2Field) GetCreatedAt() Timestamp {
if p == nil || p.CreatedAt == nil {
@@ -19126,6 +19166,14 @@ func (p *ProjectV2Field) GetCreatedAt() Timestamp {
return *p.CreatedAt
}
// GetDataType returns the DataType field if it's non-nil, zero value otherwise.
func (p *ProjectV2Field) GetDataType() string {
if p == nil || p.DataType == nil {
return ""
}
return *p.DataType
}
// GetID returns the ID field if it's non-nil, zero value otherwise.
func (p *ProjectV2Field) GetID() int64 {
if p == nil || p.ID == nil {
@@ -19134,6 +19182,30 @@ func (p *ProjectV2Field) GetID() int64 {
return *p.ID
}
// GetName returns the Name field if it's non-nil, zero value otherwise.
func (p *ProjectV2Field) GetName() string {
if p == nil || p.Name == nil {
return ""
}
return *p.Name
}
// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
func (p *ProjectV2Field) GetNodeID() string {
if p == nil || p.NodeID == nil {
return ""
}
return *p.NodeID
}
// GetProjectURL returns the ProjectURL field if it's non-nil, zero value otherwise.
func (p *ProjectV2Field) GetProjectURL() string {
if p == nil || p.ProjectURL == nil {
return ""
}
return *p.ProjectURL
}
// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
func (p *ProjectV2Field) GetUpdatedAt() Timestamp {
if p == nil || p.UpdatedAt == nil {
@@ -19142,6 +19214,86 @@ func (p *ProjectV2Field) GetUpdatedAt() Timestamp {
return *p.UpdatedAt
}
// GetDuration returns the Duration field if it's non-nil, zero value otherwise.
func (p *ProjectV2FieldConfiguration) GetDuration() int {
if p == nil || p.Duration == nil {
return 0
}
return *p.Duration
}
// GetStartDay returns the StartDay field if it's non-nil, zero value otherwise.
func (p *ProjectV2FieldConfiguration) GetStartDay() int {
if p == nil || p.StartDay == nil {
return 0
}
return *p.StartDay
}
// GetDuration returns the Duration field if it's non-nil, zero value otherwise.
func (p *ProjectV2FieldIteration) GetDuration() int {
if p == nil || p.Duration == nil {
return 0
}
return *p.Duration
}
// GetID returns the ID field if it's non-nil, zero value otherwise.
func (p *ProjectV2FieldIteration) GetID() string {
if p == nil || p.ID == nil {
return ""
}
return *p.ID
}
// GetStartDate returns the StartDate field if it's non-nil, zero value otherwise.
func (p *ProjectV2FieldIteration) GetStartDate() string {
if p == nil || p.StartDate == nil {
return ""
}
return *p.StartDate
}
// GetTitle returns the Title field if it's non-nil, zero value otherwise.
func (p *ProjectV2FieldIteration) GetTitle() string {
if p == nil || p.Title == nil {
return ""
}
return *p.Title
}
// GetColor returns the Color field if it's non-nil, zero value otherwise.
func (p *ProjectV2FieldOption) GetColor() string {
if p == nil || p.Color == nil {
return ""
}
return *p.Color
}
// GetDescription returns the Description field if it's non-nil, zero value otherwise.
func (p *ProjectV2FieldOption) GetDescription() string {
if p == nil || p.Description == nil {
return ""
}
return *p.Description
}
// GetID returns the ID field if it's non-nil, zero value otherwise.
func (p *ProjectV2FieldOption) GetID() string {
if p == nil || p.ID == nil {
return ""
}
return *p.ID
}
// GetName returns the Name field if it's non-nil, zero value otherwise.
func (p *ProjectV2FieldOption) GetName() string {
if p == nil || p.Name == nil {
return ""
}
return *p.Name
}
// GetArchivedAt returns the ArchivedAt field if it's non-nil, zero value otherwise.
func (p *ProjectV2Item) GetArchivedAt() Timestamp {
if p == nil || p.ArchivedAt == nil {
@@ -19190,6 +19342,14 @@ func (p *ProjectV2Item) GetID() int64 {
return *p.ID
}
// GetItemURL returns the ItemURL field if it's non-nil, zero value otherwise.
func (p *ProjectV2Item) GetItemURL() string {
if p == nil || p.ItemURL == nil {
return ""
}
return *p.ItemURL
}
// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
func (p *ProjectV2Item) GetNodeID() string {
if p == nil || p.NodeID == nil {
@@ -19206,6 +19366,14 @@ func (p *ProjectV2Item) GetProjectNodeID() string {
return *p.ProjectNodeID
}
// GetProjectURL returns the ProjectURL field if it's non-nil, zero value otherwise.
func (p *ProjectV2Item) GetProjectURL() string {
if p == nil || p.ProjectURL == nil {
return ""
}
return *p.ProjectURL
}
// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
func (p *ProjectV2Item) GetUpdatedAt() Timestamp {
if p == nil || p.UpdatedAt == nil {
@@ -28966,6 +29134,14 @@ func (u *UpdateOrganizationPrivateRegistry) GetVisibility() *PrivateRegistryVisi
return u.Visibility
}
// GetArchived returns the Archived field if it's non-nil, zero value otherwise.
func (u *UpdateProjectItemOptions) GetArchived() bool {
if u == nil || u.Archived == nil {
return false
}
return *u.Archived
}
// GetForce returns the Force field if it's non-nil, zero value otherwise.
func (u *UpdateRef) GetForce() bool {
if u == nil || u.Force == nil {
+239
View File
@@ -18288,6 +18288,50 @@ func TestListOrganizations_GetTotalCount(tt *testing.T) {
l.GetTotalCount()
}
func TestListProjectsOptions_GetQuery(tt *testing.T) {
tt.Parallel()
var zeroValue string
l := &ListProjectsOptions{Query: &zeroValue}
l.GetQuery()
l = &ListProjectsOptions{}
l.GetQuery()
l = nil
l.GetQuery()
}
func TestListProjectsPaginationOptions_GetAfter(tt *testing.T) {
tt.Parallel()
var zeroValue string
l := &ListProjectsPaginationOptions{After: &zeroValue}
l.GetAfter()
l = &ListProjectsPaginationOptions{}
l.GetAfter()
l = nil
l.GetAfter()
}
func TestListProjectsPaginationOptions_GetBefore(tt *testing.T) {
tt.Parallel()
var zeroValue string
l := &ListProjectsPaginationOptions{Before: &zeroValue}
l.GetBefore()
l = &ListProjectsPaginationOptions{}
l.GetBefore()
l = nil
l.GetBefore()
}
func TestListProjectsPaginationOptions_GetPerPage(tt *testing.T) {
tt.Parallel()
var zeroValue int
l := &ListProjectsPaginationOptions{PerPage: &zeroValue}
l.GetPerPage()
l = &ListProjectsPaginationOptions{}
l.GetPerPage()
l = nil
l.GetPerPage()
}
func TestListRepositories_GetTotalCount(tt *testing.T) {
tt.Parallel()
var zeroValue int
@@ -24825,6 +24869,14 @@ func TestProjectV2Event_GetSender(tt *testing.T) {
p.GetSender()
}
func TestProjectV2Field_GetConfiguration(tt *testing.T) {
tt.Parallel()
p := &ProjectV2Field{}
p.GetConfiguration()
p = nil
p.GetConfiguration()
}
func TestProjectV2Field_GetCreatedAt(tt *testing.T) {
tt.Parallel()
var zeroValue Timestamp
@@ -24836,6 +24888,17 @@ func TestProjectV2Field_GetCreatedAt(tt *testing.T) {
p.GetCreatedAt()
}
func TestProjectV2Field_GetDataType(tt *testing.T) {
tt.Parallel()
var zeroValue string
p := &ProjectV2Field{DataType: &zeroValue}
p.GetDataType()
p = &ProjectV2Field{}
p.GetDataType()
p = nil
p.GetDataType()
}
func TestProjectV2Field_GetID(tt *testing.T) {
tt.Parallel()
var zeroValue int64
@@ -24847,6 +24910,39 @@ func TestProjectV2Field_GetID(tt *testing.T) {
p.GetID()
}
func TestProjectV2Field_GetName(tt *testing.T) {
tt.Parallel()
var zeroValue string
p := &ProjectV2Field{Name: &zeroValue}
p.GetName()
p = &ProjectV2Field{}
p.GetName()
p = nil
p.GetName()
}
func TestProjectV2Field_GetNodeID(tt *testing.T) {
tt.Parallel()
var zeroValue string
p := &ProjectV2Field{NodeID: &zeroValue}
p.GetNodeID()
p = &ProjectV2Field{}
p.GetNodeID()
p = nil
p.GetNodeID()
}
func TestProjectV2Field_GetProjectURL(tt *testing.T) {
tt.Parallel()
var zeroValue string
p := &ProjectV2Field{ProjectURL: &zeroValue}
p.GetProjectURL()
p = &ProjectV2Field{}
p.GetProjectURL()
p = nil
p.GetProjectURL()
}
func TestProjectV2Field_GetUpdatedAt(tt *testing.T) {
tt.Parallel()
var zeroValue Timestamp
@@ -24858,6 +24954,116 @@ func TestProjectV2Field_GetUpdatedAt(tt *testing.T) {
p.GetUpdatedAt()
}
func TestProjectV2FieldConfiguration_GetDuration(tt *testing.T) {
tt.Parallel()
var zeroValue int
p := &ProjectV2FieldConfiguration{Duration: &zeroValue}
p.GetDuration()
p = &ProjectV2FieldConfiguration{}
p.GetDuration()
p = nil
p.GetDuration()
}
func TestProjectV2FieldConfiguration_GetStartDay(tt *testing.T) {
tt.Parallel()
var zeroValue int
p := &ProjectV2FieldConfiguration{StartDay: &zeroValue}
p.GetStartDay()
p = &ProjectV2FieldConfiguration{}
p.GetStartDay()
p = nil
p.GetStartDay()
}
func TestProjectV2FieldIteration_GetDuration(tt *testing.T) {
tt.Parallel()
var zeroValue int
p := &ProjectV2FieldIteration{Duration: &zeroValue}
p.GetDuration()
p = &ProjectV2FieldIteration{}
p.GetDuration()
p = nil
p.GetDuration()
}
func TestProjectV2FieldIteration_GetID(tt *testing.T) {
tt.Parallel()
var zeroValue string
p := &ProjectV2FieldIteration{ID: &zeroValue}
p.GetID()
p = &ProjectV2FieldIteration{}
p.GetID()
p = nil
p.GetID()
}
func TestProjectV2FieldIteration_GetStartDate(tt *testing.T) {
tt.Parallel()
var zeroValue string
p := &ProjectV2FieldIteration{StartDate: &zeroValue}
p.GetStartDate()
p = &ProjectV2FieldIteration{}
p.GetStartDate()
p = nil
p.GetStartDate()
}
func TestProjectV2FieldIteration_GetTitle(tt *testing.T) {
tt.Parallel()
var zeroValue string
p := &ProjectV2FieldIteration{Title: &zeroValue}
p.GetTitle()
p = &ProjectV2FieldIteration{}
p.GetTitle()
p = nil
p.GetTitle()
}
func TestProjectV2FieldOption_GetColor(tt *testing.T) {
tt.Parallel()
var zeroValue string
p := &ProjectV2FieldOption{Color: &zeroValue}
p.GetColor()
p = &ProjectV2FieldOption{}
p.GetColor()
p = nil
p.GetColor()
}
func TestProjectV2FieldOption_GetDescription(tt *testing.T) {
tt.Parallel()
var zeroValue string
p := &ProjectV2FieldOption{Description: &zeroValue}
p.GetDescription()
p = &ProjectV2FieldOption{}
p.GetDescription()
p = nil
p.GetDescription()
}
func TestProjectV2FieldOption_GetID(tt *testing.T) {
tt.Parallel()
var zeroValue string
p := &ProjectV2FieldOption{ID: &zeroValue}
p.GetID()
p = &ProjectV2FieldOption{}
p.GetID()
p = nil
p.GetID()
}
func TestProjectV2FieldOption_GetName(tt *testing.T) {
tt.Parallel()
var zeroValue string
p := &ProjectV2FieldOption{Name: &zeroValue}
p.GetName()
p = &ProjectV2FieldOption{}
p.GetName()
p = nil
p.GetName()
}
func TestProjectV2Item_GetArchivedAt(tt *testing.T) {
tt.Parallel()
var zeroValue Timestamp
@@ -24921,6 +25127,17 @@ func TestProjectV2Item_GetID(tt *testing.T) {
p.GetID()
}
func TestProjectV2Item_GetItemURL(tt *testing.T) {
tt.Parallel()
var zeroValue string
p := &ProjectV2Item{ItemURL: &zeroValue}
p.GetItemURL()
p = &ProjectV2Item{}
p.GetItemURL()
p = nil
p.GetItemURL()
}
func TestProjectV2Item_GetNodeID(tt *testing.T) {
tt.Parallel()
var zeroValue string
@@ -24943,6 +25160,17 @@ func TestProjectV2Item_GetProjectNodeID(tt *testing.T) {
p.GetProjectNodeID()
}
func TestProjectV2Item_GetProjectURL(tt *testing.T) {
tt.Parallel()
var zeroValue string
p := &ProjectV2Item{ProjectURL: &zeroValue}
p.GetProjectURL()
p = &ProjectV2Item{}
p.GetProjectURL()
p = nil
p.GetProjectURL()
}
func TestProjectV2Item_GetUpdatedAt(tt *testing.T) {
tt.Parallel()
var zeroValue Timestamp
@@ -37313,6 +37541,17 @@ func TestUpdateOrganizationPrivateRegistry_GetVisibility(tt *testing.T) {
u.GetVisibility()
}
func TestUpdateProjectItemOptions_GetArchived(tt *testing.T) {
tt.Parallel()
var zeroValue bool
u := &UpdateProjectItemOptions{Archived: &zeroValue}
u.GetArchived()
u = &UpdateProjectItemOptions{}
u.GetArchived()
u = nil
u.GetArchived()
}
func TestUpdateRef_GetForce(tt *testing.T) {
tt.Parallel()
var zeroValue bool
+338 -29
View File
@@ -57,13 +57,13 @@ func (p ProjectV2) String() string { return Stringify(p) }
// per page (max 100 per GitHub API docs).
type ListProjectsPaginationOptions struct {
// A cursor, as given in the Link header. If specified, the query only searches for events before this cursor.
Before string `url:"before,omitempty"`
Before *string `url:"before,omitempty"`
// A cursor, as given in the Link header. If specified, the query only searches for events after this cursor.
After string `url:"after,omitempty"`
After *string `url:"after,omitempty"`
// For paginated result sets, the number of results to include per page.
PerPage int `url:"per_page,omitempty"`
PerPage *int `url:"per_page,omitempty"`
}
// ListProjectsOptions specifies optional parameters to list projects for user / organization.
@@ -71,7 +71,7 @@ type ListProjectsOptions struct {
ListProjectsPaginationOptions
// Q is an optional query string to limit results to projects of the specified type.
Query string `url:"q,omitempty"`
Query *string `url:"q,omitempty"`
}
// ProjectV2FieldOption represents an option for a project field of type single_select or multi_select.
@@ -79,13 +79,31 @@ type ListProjectsOptions struct {
//
// GitHub API docs: https://docs.github.com/rest/projects/fields
type ProjectV2FieldOption struct {
ID string `json:"id,omitempty"`
// The display name of the option.
Name string `json:"name,omitempty"`
// The color associated with this option (e.g., "blue", "red").
Color string `json:"color,omitempty"`
// An optional description for this option.
Description string `json:"description,omitempty"`
ID *string `json:"id,omitempty"` // The unique identifier for this option.
Name *string `json:"name,omitempty"` // The display name of the option.
Color *string `json:"color,omitempty"` // The color associated with this option (e.g., "blue", "red").
Description *string `json:"description,omitempty"` // An optional description for this option.
}
// ProjectV2FieldIteration represents an iteration within a project field of type iteration.
// It defines a specific time-bound period that can be associated with project items.
//
// GitHub API docs: https://docs.github.com/rest/projects/fields
type ProjectV2FieldIteration struct {
ID *string `json:"id,omitempty"` // The unique identifier for the iteration.
Title *string `json:"title,omitempty"` // The title of the iteration.
StartDate *string `json:"start_date,omitempty"` // The start date of the iteration in ISO 8601 format.
Duration *int `json:"duration,omitempty"` // The duration of the iteration in seconds.
}
// ProjectV2FieldConfiguration represents the configuration for a project field of type iteration.
// It defines settings such as duration and start day for iterations within the project.
//
// GitHub API docs: https://docs.github.com/rest/projects/fields
type ProjectV2FieldConfiguration struct {
Duration *int `json:"duration,omitempty"` // The duration of the iteration field in seconds.
StartDay *int `json:"start_day,omitempty"` // The start day for the iteration.
Iterations []*ProjectV2FieldIteration `json:"iterations,omitempty"` // The list of iterations associated with the configuration.
}
// ProjectV2Field represents a field in a GitHub Projects V2 project.
@@ -93,22 +111,23 @@ type ProjectV2FieldOption struct {
//
// GitHub API docs: https://docs.github.com/rest/projects/fields
type ProjectV2Field struct {
ID *int64 `json:"id,omitempty"`
NodeID string `json:"node_id,omitempty"`
Name string `json:"name,omitempty"`
DataType string `json:"dataType,omitempty"`
URL string `json:"url,omitempty"`
Options []*any `json:"options,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
ID *int64 `json:"id,omitempty"`
NodeID *string `json:"node_id,omitempty"`
Name *string `json:"name,omitempty"`
DataType *string `json:"data_type,omitempty"`
ProjectURL *string `json:"project_url,omitempty"`
Options []*ProjectV2FieldOption `json:"options,omitempty"`
Configuration *ProjectV2FieldConfiguration `json:"configuration,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
}
// ListProjectsForOrg lists Projects V2 for an organization.
// ListOrganizationProjects lists Projects V2 for an organization.
//
// GitHub API docs: https://docs.github.com/rest/projects/projects#list-projects-for-organization
//
//meta:operation GET /orgs/{org}/projectsV2
func (s *ProjectsService) ListProjectsForOrg(ctx context.Context, org string, opts *ListProjectsOptions) ([]*ProjectV2, *Response, error) {
func (s *ProjectsService) ListOrganizationProjects(ctx context.Context, org string, opts *ListProjectsOptions) ([]*ProjectV2, *Response, error) {
u := fmt.Sprintf("orgs/%v/projectsV2", org)
u, err := addOptions(u, opts)
if err != nil {
@@ -128,12 +147,12 @@ func (s *ProjectsService) ListProjectsForOrg(ctx context.Context, org string, op
return projects, resp, nil
}
// GetProjectForOrg gets a Projects V2 project for an organization by ID.
// GetOrganizationProject gets a Projects V2 project for an organization by ID.
//
// GitHub API docs: https://docs.github.com/rest/projects/projects#get-project-for-organization
//
//meta:operation GET /orgs/{org}/projectsV2/{project_number}
func (s *ProjectsService) GetProjectForOrg(ctx context.Context, org string, projectNumber int) (*ProjectV2, *Response, error) {
func (s *ProjectsService) GetOrganizationProject(ctx context.Context, org string, projectNumber int) (*ProjectV2, *Response, error) {
u := fmt.Sprintf("orgs/%v/projectsV2/%v", org, projectNumber)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
@@ -148,12 +167,12 @@ func (s *ProjectsService) GetProjectForOrg(ctx context.Context, org string, proj
return project, resp, nil
}
// ListProjectsForUser lists Projects V2 for a user.
// ListUserProjects lists Projects V2 for a user.
//
// GitHub API docs: https://docs.github.com/rest/projects/projects#list-projects-for-user
//
//meta:operation GET /users/{username}/projectsV2
func (s *ProjectsService) ListProjectsForUser(ctx context.Context, username string, opts *ListProjectsOptions) ([]*ProjectV2, *Response, error) {
func (s *ProjectsService) ListUserProjects(ctx context.Context, username string, opts *ListProjectsOptions) ([]*ProjectV2, *Response, error) {
u := fmt.Sprintf("users/%v/projectsV2", username)
u, err := addOptions(u, opts)
if err != nil {
@@ -172,12 +191,12 @@ func (s *ProjectsService) ListProjectsForUser(ctx context.Context, username stri
return projects, resp, nil
}
// GetProjectForUser gets a Projects V2 project for a user by ID.
// GetUserProject gets a Projects V2 project for a user by ID.
//
// GitHub API docs: https://docs.github.com/rest/projects/projects#get-project-for-user
//
//meta:operation GET /users/{username}/projectsV2/{project_number}
func (s *ProjectsService) GetProjectForUser(ctx context.Context, username string, projectNumber int) (*ProjectV2, *Response, error) {
func (s *ProjectsService) GetUserProject(ctx context.Context, username string, projectNumber int) (*ProjectV2, *Response, error) {
u := fmt.Sprintf("users/%v/projectsV2/%v", username, projectNumber)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
@@ -192,12 +211,12 @@ func (s *ProjectsService) GetProjectForUser(ctx context.Context, username string
return project, resp, nil
}
// ListProjectFieldsForOrg lists Projects V2 for an organization.
// ListOrganizationProjectFields lists Projects V2 for an organization.
//
// GitHub API docs: https://docs.github.com/rest/projects/fields#list-project-fields-for-organization
//
//meta:operation GET /orgs/{org}/projectsV2/{project_number}/fields
func (s *ProjectsService) ListProjectFieldsForOrg(ctx context.Context, org string, projectNumber int, opts *ListProjectsOptions) ([]*ProjectV2Field, *Response, error) {
func (s *ProjectsService) ListOrganizationProjectFields(ctx context.Context, org string, projectNumber int, opts *ListProjectsOptions) ([]*ProjectV2Field, *Response, error) {
u := fmt.Sprintf("orgs/%v/projectsV2/%v/fields", org, projectNumber)
u, err := addOptions(u, opts)
if err != nil {
@@ -216,3 +235,293 @@ func (s *ProjectsService) ListProjectFieldsForOrg(ctx context.Context, org strin
}
return fields, resp, nil
}
// ListUserProjectFields lists Projects V2 for a user.
//
// GitHub API docs: https://docs.github.com/rest/projects/fields#list-project-fields-for-user
//
//meta:operation GET /users/{username}/projectsV2/{project_number}/fields
func (s *ProjectsService) ListUserProjectFields(ctx context.Context, user string, projectNumber int, opts *ListProjectsOptions) ([]*ProjectV2Field, *Response, error) {
u := fmt.Sprintf("users/%v/projectsV2/%v/fields", user, projectNumber)
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 fields []*ProjectV2Field
resp, err := s.client.Do(ctx, req, &fields)
if err != nil {
return nil, resp, err
}
return fields, resp, nil
}
// GetOrganizationProjectField gets a single project field from an organization owned project.
//
// GitHub API docs: https://docs.github.com/rest/projects/fields#get-project-field-for-organization
//
//meta:operation GET /orgs/{org}/projectsV2/{project_number}/fields/{field_id}
func (s *ProjectsService) GetOrganizationProjectField(ctx context.Context, org string, projectNumber int, fieldID int64) (*ProjectV2Field, *Response, error) {
u := fmt.Sprintf("orgs/%v/projectsV2/%v/fields/%v", org, projectNumber, fieldID)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
field := new(ProjectV2Field)
resp, err := s.client.Do(ctx, req, field)
if err != nil {
return nil, resp, err
}
return field, resp, nil
}
// GetUserProjectField gets a single project field from a user owned project.
//
// GitHub API docs: https://docs.github.com/rest/projects/fields#get-project-field-for-user
//
//meta:operation GET /users/{username}/projectsV2/{project_number}/fields/{field_id}
func (s *ProjectsService) GetUserProjectField(ctx context.Context, user string, projectNumber int, fieldID int64) (*ProjectV2Field, *Response, error) {
u := fmt.Sprintf("users/%v/projectsV2/%v/fields/%v", user, projectNumber, fieldID)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
field := new(ProjectV2Field)
resp, err := s.client.Do(ctx, req, field)
if err != nil {
return nil, resp, err
}
return field, resp, nil
}
// ListProjectItemsOptions specifies optional parameters when listing project items.
// Note: Pagination uses before/after cursor-style pagination similar to ListProjectsOptions.
// "Fields" can be used to restrict which field values are returned (by their numeric IDs).
type ListProjectItemsOptions struct {
// Embed ListProjectsOptions to reuse pagination and query parameters.
ListProjectsOptions
// Fields restricts which field values are returned by numeric field IDs.
Fields []int64 `url:"fields,omitempty,comma"`
}
// GetProjectItemOptions specifies optional parameters when getting a project item.
type GetProjectItemOptions struct {
// Fields restricts which field values are returned by numeric field IDs.
Fields []int64 `url:"fields,omitempty,comma"`
}
// AddProjectItemOptions represents the payload to add an item (issue or pull request)
// to a project. The Type must be either "Issue" or "PullRequest" (as per API docs) and
// ID is the numerical ID of that issue or pull request.
type AddProjectItemOptions struct {
Type string `json:"type,omitempty"`
ID int64 `json:"id,omitempty"`
}
// UpdateProjectItemOptions represents fields that can be modified for a project item.
// Currently the REST API allows archiving/unarchiving an item (archived boolean).
// This struct can be expanded in the future as the API grows.
type UpdateProjectItemOptions struct {
// Archived indicates whether the item should be archived (true) or unarchived (false).
Archived *bool `json:"archived,omitempty"`
// Fields allows updating field values for the item. Each entry supplies a field ID and a value.
Fields []*ProjectV2Field `json:"fields,omitempty"`
}
// ListOrganizationProjectItems lists items for an organization owned project.
//
// GitHub API docs: https://docs.github.com/rest/projects/items#list-items-for-an-organization-owned-project
//
//meta:operation GET /orgs/{org}/projectsV2/{project_number}/items
func (s *ProjectsService) ListOrganizationProjectItems(ctx context.Context, org string, projectNumber int, opts *ListProjectItemsOptions) ([]*ProjectV2Item, *Response, error) {
u := fmt.Sprintf("orgs/%v/projectsV2/%v/items", org, projectNumber)
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 items []*ProjectV2Item
resp, err := s.client.Do(ctx, req, &items)
if err != nil {
return nil, resp, err
}
return items, resp, nil
}
// AddOrganizationProjectItem adds an issue or pull request item to an organization owned project.
//
// GitHub API docs: https://docs.github.com/rest/projects/items#add-item-to-organization-owned-project
//
//meta:operation POST /orgs/{org}/projectsV2/{project_number}/items
func (s *ProjectsService) AddOrganizationProjectItem(ctx context.Context, org string, projectNumber int, opts *AddProjectItemOptions) (*ProjectV2Item, *Response, error) {
u := fmt.Sprintf("orgs/%v/projectsV2/%v/items", org, projectNumber)
req, err := s.client.NewRequest("POST", u, opts)
if err != nil {
return nil, nil, err
}
item := new(ProjectV2Item)
resp, err := s.client.Do(ctx, req, item)
if err != nil {
return nil, resp, err
}
return item, resp, nil
}
// GetOrganizationProjectItem gets a single item from an organization owned project.
//
// GitHub API docs: https://docs.github.com/rest/projects/items#get-an-item-for-an-organization-owned-project
//
//meta:operation GET /orgs/{org}/projectsV2/{project_number}/items/{item_id}
func (s *ProjectsService) GetOrganizationProjectItem(ctx context.Context, org string, projectNumber int, itemID int64, opts *GetProjectItemOptions) (*ProjectV2Item, *Response, error) {
u := fmt.Sprintf("orgs/%v/projectsV2/%v/items/%v", org, projectNumber, itemID)
req, err := s.client.NewRequest("GET", u, opts)
if err != nil {
return nil, nil, err
}
item := new(ProjectV2Item)
resp, err := s.client.Do(ctx, req, item)
if err != nil {
return nil, resp, err
}
return item, resp, nil
}
// UpdateOrganizationProjectItem updates an item in an organization owned project.
//
// GitHub API docs: https://docs.github.com/rest/projects/items#update-project-item-for-organization
//
//meta:operation PATCH /orgs/{org}/projectsV2/{project_number}/items/{item_id}
func (s *ProjectsService) UpdateOrganizationProjectItem(ctx context.Context, org string, projectNumber int, itemID int64, opts *UpdateProjectItemOptions) (*ProjectV2Item, *Response, error) {
u := fmt.Sprintf("orgs/%v/projectsV2/%v/items/%v", org, projectNumber, itemID)
req, err := s.client.NewRequest("PATCH", u, opts)
if err != nil {
return nil, nil, err
}
item := new(ProjectV2Item)
resp, err := s.client.Do(ctx, req, item)
if err != nil {
return nil, resp, err
}
return item, resp, nil
}
// DeleteOrganizationProjectItem deletes an item from an organization owned project.
//
// GitHub API docs: https://docs.github.com/rest/projects/items#delete-project-item-for-organization
//
//meta:operation DELETE /orgs/{org}/projectsV2/{project_number}/items/{item_id}
func (s *ProjectsService) DeleteOrganizationProjectItem(ctx context.Context, org string, projectNumber int, itemID int64) (*Response, error) {
u := fmt.Sprintf("orgs/%v/projectsV2/%v/items/%v", org, projectNumber, itemID)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}
// ListUserProjectItems lists items for a user owned project.
//
// GitHub API docs: https://docs.github.com/rest/projects/items#list-items-for-a-user-owned-project
//
//meta:operation GET /users/{username}/projectsV2/{project_number}/items
func (s *ProjectsService) ListUserProjectItems(ctx context.Context, username string, projectNumber int, opts *ListProjectItemsOptions) ([]*ProjectV2Item, *Response, error) {
u := fmt.Sprintf("users/%v/projectsV2/%v/items", username, projectNumber)
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 items []*ProjectV2Item
resp, err := s.client.Do(ctx, req, &items)
if err != nil {
return nil, resp, err
}
return items, resp, nil
}
// AddUserProjectItem adds an issue or pull request item to a user owned project.
//
// GitHub API docs: https://docs.github.com/rest/projects/items#add-item-to-user-owned-project
//
//meta:operation POST /users/{username}/projectsV2/{project_number}/items
func (s *ProjectsService) AddUserProjectItem(ctx context.Context, username string, projectNumber int, opts *AddProjectItemOptions) (*ProjectV2Item, *Response, error) {
u := fmt.Sprintf("users/%v/projectsV2/%v/items", username, projectNumber)
req, err := s.client.NewRequest("POST", u, opts)
if err != nil {
return nil, nil, err
}
item := new(ProjectV2Item)
resp, err := s.client.Do(ctx, req, item)
if err != nil {
return nil, resp, err
}
return item, resp, nil
}
// GetUserProjectItem gets a single item from a user owned project.
//
// GitHub API docs: https://docs.github.com/rest/projects/items#get-an-item-for-a-user-owned-project
//
//meta:operation GET /users/{username}/projectsV2/{project_number}/items/{item_id}
func (s *ProjectsService) GetUserProjectItem(ctx context.Context, username string, projectNumber int, itemID int64, opts *GetProjectItemOptions) (*ProjectV2Item, *Response, error) {
u := fmt.Sprintf("users/%v/projectsV2/%v/items/%v", username, projectNumber, itemID)
req, err := s.client.NewRequest("GET", u, opts)
if err != nil {
return nil, nil, err
}
item := new(ProjectV2Item)
resp, err := s.client.Do(ctx, req, item)
if err != nil {
return nil, resp, err
}
return item, resp, nil
}
// UpdateUserProjectItem updates an item in a user owned project.
//
// GitHub API docs: https://docs.github.com/rest/projects/items#update-project-item-for-user
//
//meta:operation PATCH /users/{username}/projectsV2/{project_number}/items/{item_id}
func (s *ProjectsService) UpdateUserProjectItem(ctx context.Context, username string, projectNumber int, itemID int64, opts *UpdateProjectItemOptions) (*ProjectV2Item, *Response, error) {
u := fmt.Sprintf("users/%v/projectsV2/%v/items/%v", username, projectNumber, itemID)
req, err := s.client.NewRequest("PATCH", u, opts)
if err != nil {
return nil, nil, err
}
item := new(ProjectV2Item)
resp, err := s.client.Do(ctx, req, item)
if err != nil {
return nil, resp, err
}
return item, resp, nil
}
// DeleteUserProjectItem deletes an item from a user owned project.
//
// GitHub API docs: https://docs.github.com/rest/projects/items#delete-project-item-for-user
//
//meta:operation DELETE /users/{username}/projectsV2/{project_number}/items/{item_id}
func (s *ProjectsService) DeleteUserProjectItem(ctx context.Context, username string, projectNumber int, itemID int64) (*Response, error) {
u := fmt.Sprintf("users/%v/projectsV2/%v/items/%v", username, projectNumber, itemID)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}
+825 -213
View File
File diff suppressed because it is too large. Load diff
+12 -12
View File
@@ -41,10 +41,10 @@ func TestProjectsV2_Org(t *testing.T) {
opts := &github.ListProjectsOptions{}
// List projects for org; pick the first available project we can read.
projects, _, err := client.Projects.ListProjectsForOrg(ctx, org, opts)
projects, _, err := client.Projects.ListOrganizationProjects(ctx, org, opts)
if err != nil {
// If listing itself fails, abort this test.
t.Fatalf("Projects.ListProjectsForOrg returned error: %v", err)
t.Fatalf("Projects.ListOrganizationProjects returned error: %v", err)
}
if len(projects) == 0 {
t.Skipf("no Projects V2 found for org %s", org)
@@ -56,19 +56,19 @@ func TestProjectsV2_Org(t *testing.T) {
projectNumber := *project.Number
// Re-fetch via Get to exercise endpoint explicitly.
proj, _, err := client.Projects.GetProjectForOrg(ctx, org, projectNumber)
proj, _, err := client.Projects.GetOrganizationProject(ctx, org, projectNumber)
if err != nil {
// Permission mismatch? Skip CRUD while still reporting failure would make the test fail;
// we want correctness so treat as fatal here.
t.Fatalf("Projects.GetProjectForOrg returned error: %v", err)
t.Fatalf("Projects.GetOrganizationProject returned error: %v", err)
}
if proj.Number == nil || *proj.Number != projectNumber {
t.Fatalf("GetProjectForOrg returned unexpected project number: got %+v want %d", proj.Number, projectNumber)
t.Fatalf("GetOrganizationProject returned unexpected project number: got %+v want %d", proj.Number, projectNumber)
}
_, _, err = client.Projects.ListProjectFieldsForOrg(ctx, org, projectNumber, nil)
_, _, err = client.Projects.ListOrganizationProjectFields(ctx, org, projectNumber, nil)
if err != nil {
t.Fatalf("Projects.ListProjectFieldsForOrg returned error: %v. Fields listing might require extra permissions", err)
t.Fatalf("Projects.ListOrganizationProjectFields returned error: %v. Fields listing might require extra permissions", err)
}
}
@@ -81,9 +81,9 @@ func TestProjectsV2_User(t *testing.T) {
ctx := t.Context()
opts := &github.ListProjectsOptions{}
projects, _, err := client.Projects.ListProjectsForUser(ctx, user, opts)
projects, _, err := client.Projects.ListUserProjects(ctx, user, opts)
if err != nil {
t.Fatalf("Projects.ListProjectsForUser returned error: %v. This indicates API or permission issue", err)
t.Fatalf("Projects.ListUserProjects returned error: %v. This indicates API or permission issue", err)
}
if len(projects) == 0 {
t.Skipf("no Projects V2 found for user %s", user)
@@ -93,12 +93,12 @@ func TestProjectsV2_User(t *testing.T) {
t.Skip("selected user project has nil Number field")
}
proj, _, err := client.Projects.GetProjectForUser(ctx, user, *project.Number)
proj, _, err := client.Projects.GetUserProject(ctx, user, *project.Number)
if err != nil {
// can't fetch specific project; treat as fatal
t.Fatalf("Projects.GetProjectForUser returned error: %v", err)
t.Fatalf("Projects.GetUserProject returned error: %v", err)
}
if proj.Number == nil || *proj.Number != *project.Number {
t.Fatalf("GetProjectForUser returned unexpected project number: got %+v want %d", proj.Number, *project.Number)
t.Fatalf("GetUserProject returned unexpected project number: got %+v want %d", proj.Number, *project.Number)
}
}