mirror of
https://github.com/google/go-github.git
synced 2026-10-29 00:44:52 +08:00
1056 lines
41 KiB
Go
1056 lines
41 KiB
Go
// 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"
|
|
"encoding/json"
|
|
"fmt"
|
|
"strconv"
|
|
)
|
|
|
|
// ProjectsService handles communication with the project V2
|
|
// methods of the GitHub API.
|
|
//
|
|
// GitHub API docs: https://docs.github.com/rest/projects?apiVersion=2022-11-28
|
|
type ProjectsService service
|
|
|
|
// ProjectV2ItemContentType represents the type of content in a ProjectV2Item.
|
|
type ProjectV2ItemContentType string
|
|
|
|
// This is the set of possible content types for a ProjectV2Item.
|
|
const (
|
|
ProjectV2ItemContentTypeDraftIssue ProjectV2ItemContentType = "DraftIssue"
|
|
ProjectV2ItemContentTypeIssue ProjectV2ItemContentType = "Issue"
|
|
ProjectV2ItemContentTypePullRequest ProjectV2ItemContentType = "PullRequest"
|
|
)
|
|
|
|
// ProjectV2StatusUpdate represents a status update for a project.
|
|
type ProjectV2StatusUpdate struct {
|
|
ID *int64 `json:"id,omitempty"`
|
|
NodeID *string `json:"node_id,omitempty"`
|
|
ProjectNodeID *string `json:"project_node_id,omitempty"`
|
|
Creator *User `json:"creator,omitempty"`
|
|
CreatedAt *Timestamp `json:"created_at,omitempty"`
|
|
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
|
|
// Status can be one of: "INACTIVE", "ON_TRACK", "AT_RISK", "OFF_TRACK", "COMPLETE".
|
|
Status *string `json:"status,omitempty"`
|
|
StartDate *string `json:"start_date,omitempty"`
|
|
TargetDate *string `json:"target_date,omitempty"`
|
|
Body *string `json:"body,omitempty"`
|
|
}
|
|
|
|
// ProjectV2DraftIssue represents a draft issue in a project.
|
|
type ProjectV2DraftIssue struct {
|
|
ID *int64 `json:"id,omitempty"`
|
|
NodeID *string `json:"node_id,omitempty"`
|
|
Title *string `json:"title,omitempty"`
|
|
Body *string `json:"body,omitempty"`
|
|
User *User `json:"user,omitempty"`
|
|
CreatedAt *Timestamp `json:"created_at,omitempty"`
|
|
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
|
|
}
|
|
|
|
// ProjectV2 represents a v2 project.
|
|
type ProjectV2 struct {
|
|
ID *int64 `json:"id,omitempty"`
|
|
NodeID *string `json:"node_id,omitempty"`
|
|
Owner *User `json:"owner,omitempty"`
|
|
Creator *User `json:"creator,omitempty"`
|
|
Title *string `json:"title,omitempty"`
|
|
Description *string `json:"description,omitempty"`
|
|
Public *bool `json:"public,omitempty"`
|
|
ClosedAt *Timestamp `json:"closed_at,omitempty"`
|
|
CreatedAt *Timestamp `json:"created_at,omitempty"`
|
|
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
|
|
DeletedAt *Timestamp `json:"deleted_at,omitempty"`
|
|
Number *int `json:"number,omitempty"`
|
|
ShortDescription *string `json:"short_description,omitempty"`
|
|
DeletedBy *User `json:"deleted_by,omitempty"`
|
|
State *string `json:"state,omitempty"`
|
|
LatestStatusUpdate *ProjectV2StatusUpdate `json:"latest_status_update,omitempty"`
|
|
IsTemplate *bool `json:"is_template,omitempty"`
|
|
|
|
// Fields migrated from the Project (classic) struct:
|
|
URL *string `json:"url,omitempty"`
|
|
HTMLURL *string `json:"html_url,omitempty"`
|
|
ColumnsURL *string `json:"columns_url,omitempty"`
|
|
OwnerURL *string `json:"owner_url,omitempty"`
|
|
Name *string `json:"name,omitempty"`
|
|
Body *string `json:"body,omitempty"`
|
|
OrganizationPermission *string `json:"organization_permission,omitempty"`
|
|
Private *bool `json:"private,omitempty"`
|
|
}
|
|
|
|
func (p ProjectV2) String() string { return Stringify(p) }
|
|
|
|
// ListProjectsPaginationOptions specifies optional parameters to list projects for user / organization.
|
|
//
|
|
// Note: Pagination is powered by before/after cursor-style pagination. After the initial call,
|
|
// inspect the returned *Response. Use resp.After as the opts.After value to request
|
|
// the next page, and resp.Before as the opts.Before value to request the previous
|
|
// page. Set either Before or After for a request; if both are
|
|
// supplied GitHub API will return an error. PerPage controls the number of items
|
|
// 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"`
|
|
|
|
// A cursor, as given in the Link header. If specified, the query only searches for events after this cursor.
|
|
After string `url:"after,omitempty"`
|
|
|
|
// For paginated result sets, the number of results to include per page.
|
|
PerPage int `url:"per_page,omitempty"`
|
|
}
|
|
|
|
// ListProjectsOptions specifies optional parameters to list projects for user / organization.
|
|
type ListProjectsOptions struct {
|
|
ListProjectsPaginationOptions
|
|
|
|
// Q is an optional query string to limit results to projects of the specified type.
|
|
Query string `url:"q,omitempty"`
|
|
}
|
|
|
|
// ProjectV2TextContent represents text content in a project field option or iteration.
|
|
// It includes both HTML and raw text representations.
|
|
//
|
|
// GitHub API docs: https://docs.github.com/rest/projects/fields?apiVersion=2022-11-28
|
|
type ProjectV2TextContent struct {
|
|
HTML *string `json:"html,omitempty"`
|
|
Raw *string `json:"raw,omitempty"`
|
|
}
|
|
|
|
// ProjectV2FieldOption represents an option for a project field of type single_select or multi_select.
|
|
// It defines the available choices that can be selected for dropdown-style fields.
|
|
//
|
|
// GitHub API docs: https://docs.github.com/rest/projects/fields?apiVersion=2022-11-28
|
|
type ProjectV2FieldOption struct {
|
|
ID *string `json:"id,omitempty"` // The unique identifier for this option.
|
|
Color *string `json:"color,omitempty"` // The color associated with this option (e.g., "blue", "red").
|
|
Description *ProjectV2TextContent `json:"description,omitempty"` // An optional description for this option.
|
|
Name *ProjectV2TextContent `json:"name,omitempty"` // The display name of the 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?apiVersion=2022-11-28
|
|
type ProjectV2FieldIteration struct {
|
|
ID *string `json:"id,omitempty"` // The unique identifier for the iteration.
|
|
Title *ProjectV2TextContent `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?apiVersion=2022-11-28
|
|
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.
|
|
}
|
|
|
|
// ProjectV2ItemContent is a union type that holds the content of a ProjectV2Item.
|
|
// The actual type depends on the ContentType field of the parent ProjectV2Item.
|
|
// Only one of the fields will be populated after unmarshaling.
|
|
type ProjectV2ItemContent struct {
|
|
Issue *Issue `json:"-"`
|
|
PullRequest *PullRequest `json:"-"`
|
|
DraftIssue *ProjectV2DraftIssue `json:"-"`
|
|
}
|
|
|
|
// MarshalJSON implements custom marshaling for ProjectV2ItemContent.
|
|
func (c ProjectV2ItemContent) MarshalJSON() ([]byte, error) {
|
|
if c.Issue != nil {
|
|
return json.Marshal(c.Issue)
|
|
}
|
|
if c.PullRequest != nil {
|
|
return json.Marshal(c.PullRequest)
|
|
}
|
|
if c.DraftIssue != nil {
|
|
return json.Marshal(c.DraftIssue)
|
|
}
|
|
return []byte("null"), nil
|
|
}
|
|
|
|
// ProjectV2Item represents a full project item with field values.
|
|
// This type is used by Get, List, and Update operations which return field values.
|
|
// The Content field is automatically unmarshaled into the appropriate type based on ContentType.
|
|
type ProjectV2Item struct {
|
|
ArchivedAt *Timestamp `json:"archived_at,omitempty"`
|
|
Content *ProjectV2ItemContent `json:"content,omitempty"`
|
|
ContentType *ProjectV2ItemContentType `json:"content_type,omitempty"`
|
|
CreatedAt *Timestamp `json:"created_at,omitempty"`
|
|
Creator *User `json:"creator,omitempty"`
|
|
Fields []*ProjectV2ItemFieldValue `json:"fields,omitempty"`
|
|
ID *int64 `json:"id,omitempty"`
|
|
ItemURL *string `json:"item_url,omitempty"`
|
|
NodeID *string `json:"node_id,omitempty"`
|
|
ProjectURL *string `json:"project_url,omitempty"`
|
|
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
|
|
|
|
// ProjectNodeID and ContentNodeID are used in ProjectsV2Item Webhook payloads.
|
|
// They may not be populated in all API responses, but are included here for completeness.
|
|
// See: https://docs.github.com/en/webhooks/webhook-events-and-payloads#projects_v2_item
|
|
ProjectNodeID *string `json:"project_node_id,omitempty"`
|
|
ContentNodeID *string `json:"content_node_id,omitempty"`
|
|
}
|
|
|
|
// UnmarshalJSON implements custom unmarshaling for ProjectV2Item.
|
|
// It uses the ContentType field to determine how to unmarshal the Content field.
|
|
func (p *ProjectV2Item) UnmarshalJSON(data []byte) error {
|
|
type contentAlias ProjectV2Item
|
|
|
|
aux := &struct {
|
|
Content json.RawMessage `json:"content,omitempty"`
|
|
*contentAlias
|
|
}{
|
|
contentAlias: (*contentAlias)(p),
|
|
}
|
|
|
|
if err := json.Unmarshal(data, aux); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Now unmarshal the content based on ContentType
|
|
if len(aux.Content) > 0 && string(aux.Content) != "null" && p.ContentType != nil {
|
|
p.Content = &ProjectV2ItemContent{}
|
|
switch *p.ContentType {
|
|
case ProjectV2ItemContentTypeIssue:
|
|
p.Content.Issue = &Issue{}
|
|
return json.Unmarshal(aux.Content, p.Content.Issue)
|
|
case ProjectV2ItemContentTypePullRequest:
|
|
p.Content.PullRequest = &PullRequest{}
|
|
return json.Unmarshal(aux.Content, p.Content.PullRequest)
|
|
case ProjectV2ItemContentTypeDraftIssue:
|
|
p.Content.DraftIssue = &ProjectV2DraftIssue{}
|
|
return json.Unmarshal(aux.Content, p.Content.DraftIssue)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// ProjectV2Field represents a field in a GitHub Projects V2 project.
|
|
// Fields define the structure and data types for project items.
|
|
//
|
|
// GitHub API docs: https://docs.github.com/rest/projects/fields?apiVersion=2022-11-28
|
|
type ProjectV2Field struct {
|
|
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"`
|
|
}
|
|
|
|
// ProjectV2ItemFieldValue represents a field value of a project item.
|
|
type ProjectV2ItemFieldValue struct {
|
|
ID *int64 `json:"id,omitempty"`
|
|
Name *string `json:"name,omitempty"`
|
|
DataType *string `json:"data_type,omitempty"`
|
|
// Value set for the field. The type depends on the field type:
|
|
// - text: string
|
|
// - number: float64
|
|
// - date: string (ISO 8601 date format, e.g. "2023-06-23") or null
|
|
// - single_select: object with "id", "name", "color", "description" fields or null
|
|
// - iteration: object with "id", "title", "start_date", "duration" fields or null
|
|
// - title: object with "text" field (read-only, reflects the item's title) or null
|
|
// - assignees: array of user objects with "login", "id", etc. or null
|
|
// - labels: array of label objects with "id", "name", "color", etc. or null
|
|
// - linked_pull_requests: array of pull request objects or null
|
|
// - milestone: milestone object with "id", "title", "description", etc. or null
|
|
// - repository: repository object with "id", "name", "full_name", etc. or null
|
|
// - reviewers: array of user objects or null
|
|
// - status: object with "id", "name", "color", "description" fields (same structure as single_select) or null
|
|
Value any `json:"value,omitempty"`
|
|
}
|
|
|
|
// ListOrganizationProjects lists Projects V2 for an organization.
|
|
//
|
|
// GitHub API docs: https://docs.github.com/rest/projects/projects?apiVersion=2022-11-28#list-projects-for-organization
|
|
//
|
|
//meta:operation GET /orgs/{org}/projectsV2
|
|
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 {
|
|
return nil, nil, err
|
|
}
|
|
|
|
req, err := s.client.NewRequest(ctx, "GET", u, nil)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
var projects []*ProjectV2
|
|
resp, err := s.client.Do(req, &projects)
|
|
if err != nil {
|
|
return nil, resp, err
|
|
}
|
|
|
|
return projects, resp, nil
|
|
}
|
|
|
|
// GetOrganizationProject gets a Projects V2 project for an organization by ID.
|
|
//
|
|
// GitHub API docs: https://docs.github.com/rest/projects/projects?apiVersion=2022-11-28#get-project-for-organization
|
|
//
|
|
//meta:operation GET /orgs/{org}/projectsV2/{project_number}
|
|
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(ctx, "GET", u, nil)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
var project *ProjectV2
|
|
resp, err := s.client.Do(req, &project)
|
|
if err != nil {
|
|
return nil, resp, err
|
|
}
|
|
|
|
return project, resp, nil
|
|
}
|
|
|
|
// ListUserProjects lists Projects V2 for a user.
|
|
//
|
|
// GitHub API docs: https://docs.github.com/rest/projects/projects?apiVersion=2022-11-28#list-projects-for-user
|
|
//
|
|
//meta:operation GET /users/{username}/projectsV2
|
|
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 {
|
|
return nil, nil, err
|
|
}
|
|
req, err := s.client.NewRequest(ctx, "GET", u, nil)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
var projects []*ProjectV2
|
|
resp, err := s.client.Do(req, &projects)
|
|
if err != nil {
|
|
return nil, resp, err
|
|
}
|
|
|
|
return projects, resp, nil
|
|
}
|
|
|
|
// GetUserProject gets a Projects V2 project for a user by ID.
|
|
//
|
|
// GitHub API docs: https://docs.github.com/rest/projects/projects?apiVersion=2022-11-28#get-project-for-user
|
|
//
|
|
//meta:operation GET /users/{username}/projectsV2/{project_number}
|
|
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(ctx, "GET", u, nil)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
var project *ProjectV2
|
|
resp, err := s.client.Do(req, &project)
|
|
if err != nil {
|
|
return nil, resp, err
|
|
}
|
|
|
|
return project, resp, nil
|
|
}
|
|
|
|
// ListOrganizationProjectFields lists Projects V2 for an organization.
|
|
//
|
|
// GitHub API docs: https://docs.github.com/rest/projects/fields?apiVersion=2022-11-28#list-project-fields-for-organization
|
|
//
|
|
//meta:operation GET /orgs/{org}/projectsV2/{project_number}/fields
|
|
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 {
|
|
return nil, nil, err
|
|
}
|
|
|
|
req, err := s.client.NewRequest(ctx, "GET", u, nil)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
var fields []*ProjectV2Field
|
|
resp, err := s.client.Do(req, &fields)
|
|
if err != nil {
|
|
return nil, resp, err
|
|
}
|
|
|
|
return fields, resp, nil
|
|
}
|
|
|
|
// ListUserProjectFields lists Projects V2 for a user.
|
|
//
|
|
// GitHub API docs: https://docs.github.com/rest/projects/fields?apiVersion=2022-11-28#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(ctx, "GET", u, nil)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
var fields []*ProjectV2Field
|
|
resp, err := s.client.Do(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?apiVersion=2022-11-28#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(ctx, "GET", u, nil)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
var field *ProjectV2Field
|
|
resp, err := s.client.Do(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?apiVersion=2022-11-28#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(ctx, "GET", u, nil)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
var field *ProjectV2Field
|
|
resp, err := s.client.Do(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 *ProjectV2ItemContentType `json:"type,omitempty"`
|
|
ID *int64 `json:"id,omitempty"`
|
|
}
|
|
|
|
// UpdateProjectV2Field represents a field update for a project item.
|
|
//
|
|
// GitHub API docs: https://docs.github.com/rest/projects/items?apiVersion=2022-11-28#update-project-item-for-organization
|
|
type UpdateProjectV2Field struct {
|
|
// ID is the field ID to update.
|
|
ID int64 `json:"id"`
|
|
// Value is the new value to set for the field. The type depends on the field type.
|
|
// For text fields: string
|
|
// For number fields: float64 or int
|
|
// For single_select fields: string (option ID)
|
|
// For date fields: string (ISO 8601 date)
|
|
// For iteration fields: string (iteration ID)
|
|
// Note: Some field types (title, assignees, labels, etc.) are read-only or managed through other API endpoints.
|
|
Value any `json:"value"`
|
|
}
|
|
|
|
// UpdateProjectItemOptions represents fields that can be modified for a project item.
|
|
// The GitHub API expects either archived status updates or field value updates.
|
|
type UpdateProjectItemOptions struct {
|
|
// Archived indicates whether the item should be archived (true) or unarchived (false).
|
|
// This is used for archive/unarchive operations.
|
|
Archived *bool `json:"archived,omitempty"`
|
|
// Fields contains field updates to apply to the project item.
|
|
// Each entry specifies a field ID and its new value.
|
|
Fields []*UpdateProjectV2Field `json:"fields,omitempty"`
|
|
}
|
|
|
|
// ListOrganizationProjectItems lists items for an organization owned project.
|
|
//
|
|
// GitHub API docs: https://docs.github.com/rest/projects/items?apiVersion=2022-11-28#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(ctx, "GET", u, nil)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
var items []*ProjectV2Item
|
|
resp, err := s.client.Do(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?apiVersion=2022-11-28#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, body *AddProjectItemOptions) (*ProjectV2Item, *Response, error) {
|
|
u := fmt.Sprintf("orgs/%v/projectsV2/%v/items", org, projectNumber)
|
|
req, err := s.client.NewRequest(ctx, "POST", u, body)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
var item *ProjectV2Item
|
|
resp, err := s.client.Do(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?apiVersion=2022-11-28#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)
|
|
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 item *ProjectV2Item
|
|
resp, err := s.client.Do(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?apiVersion=2022-11-28#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, body *UpdateProjectItemOptions) (*ProjectV2Item, *Response, error) {
|
|
u := fmt.Sprintf("orgs/%v/projectsV2/%v/items/%v", org, projectNumber, itemID)
|
|
req, err := s.client.NewRequest(ctx, "PATCH", u, body)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
var item *ProjectV2Item
|
|
resp, err := s.client.Do(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?apiVersion=2022-11-28#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(ctx, "DELETE", u, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return s.client.Do(req, nil)
|
|
}
|
|
|
|
// ListUserProjectItems lists items for a user owned project.
|
|
//
|
|
// GitHub API docs: https://docs.github.com/rest/projects/items?apiVersion=2022-11-28#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(ctx, "GET", u, nil)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
var items []*ProjectV2Item
|
|
resp, err := s.client.Do(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?apiVersion=2022-11-28#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, body *AddProjectItemOptions) (*ProjectV2Item, *Response, error) {
|
|
u := fmt.Sprintf("users/%v/projectsV2/%v/items", username, projectNumber)
|
|
req, err := s.client.NewRequest(ctx, "POST", u, body)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
var item *ProjectV2Item
|
|
resp, err := s.client.Do(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?apiVersion=2022-11-28#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)
|
|
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 item *ProjectV2Item
|
|
resp, err := s.client.Do(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?apiVersion=2022-11-28#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, body *UpdateProjectItemOptions) (*ProjectV2Item, *Response, error) {
|
|
u := fmt.Sprintf("users/%v/projectsV2/%v/items/%v", username, projectNumber, itemID)
|
|
req, err := s.client.NewRequest(ctx, "PATCH", u, body)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
var item *ProjectV2Item
|
|
resp, err := s.client.Do(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?apiVersion=2022-11-28#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(ctx, "DELETE", u, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return s.client.Do(req, nil)
|
|
}
|
|
|
|
// CreateProjectV2DraftItemRequest specifies the parameters to create a draft item in a project.
|
|
type CreateProjectV2DraftItemRequest struct {
|
|
// Title is the title of the draft issue item to create.
|
|
Title string `json:"title"`
|
|
// Body is the body content of the draft issue item to create.
|
|
Body *string `json:"body,omitempty"`
|
|
}
|
|
|
|
// CreateOrganizationProjectDraftItem creates a draft item in an organization owned project.
|
|
//
|
|
// GitHub API docs: https://docs.github.com/rest/projects/drafts?apiVersion=2022-11-28#create-draft-item-for-organization-owned-project
|
|
//
|
|
//meta:operation POST /orgs/{org}/projectsV2/{project_number}/drafts
|
|
func (s *ProjectsService) CreateOrganizationProjectDraftItem(ctx context.Context, org string, projectNumber int, body CreateProjectV2DraftItemRequest) (*ProjectV2Item, *Response, error) {
|
|
u := fmt.Sprintf("orgs/%v/projectsV2/%v/drafts", org, projectNumber)
|
|
req, err := s.client.NewRequest(ctx, "POST", u, body)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
var item *ProjectV2Item
|
|
resp, err := s.client.Do(req, &item)
|
|
if err != nil {
|
|
return nil, resp, err
|
|
}
|
|
|
|
return item, resp, nil
|
|
}
|
|
|
|
// CreateUserProjectDraftItem creates a draft item in a user owned project.
|
|
//
|
|
// Note: this endpoint identifies the user by their unique numeric ID (user_id)
|
|
// in the path, not by username, mirroring the GitHub REST API.
|
|
//
|
|
// GitHub API docs: https://docs.github.com/rest/projects/drafts?apiVersion=2022-11-28#create-draft-item-for-user-owned-project
|
|
//
|
|
//meta:operation POST /user/{user_id}/projectsV2/{project_number}/drafts
|
|
func (s *ProjectsService) CreateUserProjectDraftItem(ctx context.Context, userID int64, projectNumber int, body CreateProjectV2DraftItemRequest) (*ProjectV2Item, *Response, error) {
|
|
u := fmt.Sprintf("user/%v/projectsV2/%v/drafts", userID, projectNumber)
|
|
req, err := s.client.NewRequest(ctx, "POST", u, body)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
var item *ProjectV2Item
|
|
resp, err := s.client.Do(req, &item)
|
|
if err != nil {
|
|
return nil, resp, err
|
|
}
|
|
|
|
return item, resp, nil
|
|
}
|
|
|
|
// ProjectV2FieldSingleSelectOption represents an option to create for a single_select project field.
|
|
type ProjectV2FieldSingleSelectOption struct {
|
|
// Name is the display name of the option.
|
|
Name string `json:"name"`
|
|
// Color is the color associated with the option.
|
|
// One of: BLUE, GRAY, GREEN, ORANGE, PINK, PURPLE, RED, YELLOW.
|
|
Color *string `json:"color,omitempty"`
|
|
// Description is an optional description of the option.
|
|
Description *string `json:"description,omitempty"`
|
|
}
|
|
|
|
// ProjectV2FieldIterationConfiguration represents the configuration to create an iteration project field.
|
|
type ProjectV2FieldIterationConfiguration struct {
|
|
// StartDate is the start date of the first iteration in ISO 8601 (YYYY-MM-DD) format.
|
|
StartDate *string `json:"start_date,omitempty"`
|
|
// Duration is the default duration for iterations in days.
|
|
Duration *int `json:"duration,omitempty"`
|
|
// Iterations holds zero or more iterations for the field.
|
|
Iterations []*ProjectV2FieldIterationConfigurationIteration `json:"iterations,omitempty"`
|
|
}
|
|
|
|
// ProjectV2FieldIterationConfigurationIteration represents a single iteration within a ProjectV2FieldIterationConfiguration.
|
|
type ProjectV2FieldIterationConfigurationIteration struct {
|
|
// Title is the title of the iteration.
|
|
Title *string `json:"title,omitempty"`
|
|
// StartDate is the start date of the iteration in ISO 8601 (YYYY-MM-DD) format.
|
|
StartDate *string `json:"start_date,omitempty"`
|
|
// Duration is the duration of the iteration in days.
|
|
Duration *int `json:"duration,omitempty"`
|
|
}
|
|
|
|
// AddProjectV2FieldRequest specifies the parameters to add a field to a project.
|
|
//
|
|
// The GitHub API models the body as a one-of: set IssueFieldID to link a
|
|
// built-in issue field, or set Name and DataType to create a new field. When
|
|
// DataType is "single_select", SingleSelectOptions is required; when DataType
|
|
// is "iteration", IterationConfiguration is required.
|
|
type AddProjectV2FieldRequest struct {
|
|
// Name is the name of the field.
|
|
Name *string `json:"name,omitempty"`
|
|
// DataType is the field's data type.
|
|
// One of: text, number, date, single_select, iteration.
|
|
DataType *string `json:"data_type,omitempty"`
|
|
// SingleSelectOptions holds the options for a single_select field. (Required for single_select.)
|
|
SingleSelectOptions []*ProjectV2FieldSingleSelectOption `json:"single_select_options,omitempty"`
|
|
// IterationConfiguration holds the configuration for an iteration field. (Required for iteration.)
|
|
IterationConfiguration *ProjectV2FieldIterationConfiguration `json:"iteration_configuration,omitempty"`
|
|
// IssueFieldID links an existing built-in issue field to the project. (Organization owned projects only.)
|
|
IssueFieldID *int64 `json:"issue_field_id,omitempty"`
|
|
}
|
|
|
|
// AddOrganizationProjectField adds a field to an organization owned project.
|
|
//
|
|
// GitHub API docs: https://docs.github.com/rest/projects/fields?apiVersion=2022-11-28#add-a-field-to-an-organization-owned-project
|
|
//
|
|
//meta:operation POST /orgs/{org}/projectsV2/{project_number}/fields
|
|
func (s *ProjectsService) AddOrganizationProjectField(ctx context.Context, org string, projectNumber int, body AddProjectV2FieldRequest) (*ProjectV2Field, *Response, error) {
|
|
u := fmt.Sprintf("orgs/%v/projectsV2/%v/fields", org, projectNumber)
|
|
req, err := s.client.NewRequest(ctx, "POST", u, body)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
var field *ProjectV2Field
|
|
resp, err := s.client.Do(req, &field)
|
|
if err != nil {
|
|
return nil, resp, err
|
|
}
|
|
|
|
return field, resp, nil
|
|
}
|
|
|
|
// AddUserProjectField adds a field to a user owned project.
|
|
//
|
|
// GitHub API docs: https://docs.github.com/rest/projects/fields?apiVersion=2022-11-28#add-field-to-user-owned-project
|
|
//
|
|
//meta:operation POST /users/{username}/projectsV2/{project_number}/fields
|
|
func (s *ProjectsService) AddUserProjectField(ctx context.Context, username string, projectNumber int, body AddProjectV2FieldRequest) (*ProjectV2Field, *Response, error) {
|
|
u := fmt.Sprintf("users/%v/projectsV2/%v/fields", username, projectNumber)
|
|
req, err := s.client.NewRequest(ctx, "POST", u, body)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
var field *ProjectV2Field
|
|
resp, err := s.client.Do(req, &field)
|
|
if err != nil {
|
|
return nil, resp, err
|
|
}
|
|
|
|
return field, resp, nil
|
|
}
|
|
|
|
// ProjectV2View represents a view in a project.
|
|
type ProjectV2View struct {
|
|
ID int64 `json:"id"`
|
|
Number int `json:"number"`
|
|
Name string `json:"name"`
|
|
Layout string `json:"layout"`
|
|
NodeID string `json:"node_id"`
|
|
ProjectURL string `json:"project_url"`
|
|
HTMLURL string `json:"html_url"`
|
|
Creator User `json:"creator"`
|
|
Filter *string `json:"filter,omitempty"`
|
|
VisibleFields []int64 `json:"visible_fields"`
|
|
SortBy []*ProjectV2ViewSortBy `json:"sort_by"`
|
|
GroupBy []int64 `json:"group_by"`
|
|
VerticalGroupBy []int64 `json:"vertical_group_by"`
|
|
CreatedAt Timestamp `json:"created_at"`
|
|
UpdatedAt Timestamp `json:"updated_at"`
|
|
}
|
|
|
|
// ProjectV2ViewSortBy represents a single sort criterion of a project view.
|
|
//
|
|
// On the wire it is encoded as a [field_id, direction] tuple rather than an
|
|
// object, so it has custom JSON (un)marshaling.
|
|
type ProjectV2ViewSortBy struct {
|
|
// FieldID is the ID of the field to sort by.
|
|
FieldID *int64 `json:"-"`
|
|
// Direction is the sort direction, one of "asc" or "desc".
|
|
Direction *string `json:"-"`
|
|
}
|
|
|
|
// UnmarshalJSON implements custom unmarshaling for the [field_id, direction]
|
|
// tuple. The field_id may be encoded as either a number or a string.
|
|
func (s *ProjectV2ViewSortBy) UnmarshalJSON(data []byte) error {
|
|
var tuple []json.RawMessage
|
|
if err := json.Unmarshal(data, &tuple); err != nil {
|
|
return err
|
|
}
|
|
if len(tuple) != 2 {
|
|
return fmt.Errorf("expected a [field_id, direction] tuple, got %v elements", len(tuple))
|
|
}
|
|
|
|
var fieldID int64
|
|
if err := json.Unmarshal(tuple[0], &fieldID); err != nil {
|
|
// The OpenAPI schema allows the field_id to be a string as well.
|
|
var str string
|
|
if err2 := json.Unmarshal(tuple[0], &str); err2 != nil {
|
|
return fmt.Errorf("invalid field_id: %w", err2)
|
|
}
|
|
fieldID, err = strconv.ParseInt(str, 10, 64)
|
|
if err != nil {
|
|
return fmt.Errorf("invalid field_id %q: %w", str, err)
|
|
}
|
|
}
|
|
|
|
var direction string
|
|
if err := json.Unmarshal(tuple[1], &direction); err != nil {
|
|
return fmt.Errorf("invalid direction: %w", err)
|
|
}
|
|
|
|
s.FieldID = &fieldID
|
|
s.Direction = &direction
|
|
return nil
|
|
}
|
|
|
|
// MarshalJSON implements custom marshaling to the [field_id, direction] tuple.
|
|
func (s ProjectV2ViewSortBy) MarshalJSON() ([]byte, error) {
|
|
return json.Marshal([]any{s.FieldID, s.Direction})
|
|
}
|
|
|
|
// CreateProjectV2ViewRequest specifies the parameters to create a project view.
|
|
type CreateProjectV2ViewRequest struct {
|
|
// Name is the view's display name.
|
|
Name string `json:"name"`
|
|
// Layout is the view's layout. One of: table, board, roadmap.
|
|
Layout string `json:"layout"`
|
|
// Filter is an optional query string to filter the items shown in the view.
|
|
Filter *string `json:"filter,omitempty"`
|
|
// VisibleFields lists the field IDs to display. Not applicable to the roadmap layout.
|
|
VisibleFields []int64 `json:"visible_fields,omitempty"`
|
|
}
|
|
|
|
// CreateOrganizationProjectView creates a view for an organization owned project.
|
|
//
|
|
// GitHub API docs: https://docs.github.com/rest/projects/views?apiVersion=2022-11-28#create-a-view-for-an-organization-owned-project
|
|
//
|
|
//meta:operation POST /orgs/{org}/projectsV2/{project_number}/views
|
|
func (s *ProjectsService) CreateOrganizationProjectView(ctx context.Context, org string, projectNumber int, body CreateProjectV2ViewRequest) (*ProjectV2View, *Response, error) {
|
|
u := fmt.Sprintf("orgs/%v/projectsV2/%v/views", org, projectNumber)
|
|
req, err := s.client.NewRequest(ctx, "POST", u, body)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
var view *ProjectV2View
|
|
resp, err := s.client.Do(req, &view)
|
|
if err != nil {
|
|
return nil, resp, err
|
|
}
|
|
|
|
return view, resp, nil
|
|
}
|
|
|
|
// CreateUserProjectView creates a view for a user owned project.
|
|
//
|
|
// Note: this endpoint identifies the user by their unique numeric ID (user_id)
|
|
// in the path, not by username, mirroring the GitHub REST API.
|
|
//
|
|
// GitHub API docs: https://docs.github.com/rest/projects/views?apiVersion=2022-11-28#create-a-view-for-a-user-owned-project
|
|
//
|
|
//meta:operation POST /users/{user_id}/projectsV2/{project_number}/views
|
|
func (s *ProjectsService) CreateUserProjectView(ctx context.Context, userID int64, projectNumber int, body CreateProjectV2ViewRequest) (*ProjectV2View, *Response, error) {
|
|
u := fmt.Sprintf("users/%v/projectsV2/%v/views", userID, projectNumber)
|
|
req, err := s.client.NewRequest(ctx, "POST", u, body)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
var view *ProjectV2View
|
|
resp, err := s.client.Do(req, &view)
|
|
if err != nil {
|
|
return nil, resp, err
|
|
}
|
|
|
|
return view, resp, nil
|
|
}
|
|
|
|
// ListOrganizationProjectViewItems lists the items of a view in an organization owned project.
|
|
//
|
|
// GitHub API docs: https://docs.github.com/rest/projects/items?apiVersion=2022-11-28#list-items-for-an-organization-project-view
|
|
//
|
|
//meta:operation GET /orgs/{org}/projectsV2/{project_number}/views/{view_number}/items
|
|
func (s *ProjectsService) ListOrganizationProjectViewItems(ctx context.Context, org string, projectNumber, viewNumber int, opts *ListProjectItemsOptions) ([]*ProjectV2Item, *Response, error) {
|
|
u := fmt.Sprintf("orgs/%v/projectsV2/%v/views/%v/items", org, projectNumber, viewNumber)
|
|
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 items []*ProjectV2Item
|
|
resp, err := s.client.Do(req, &items)
|
|
if err != nil {
|
|
return nil, resp, err
|
|
}
|
|
|
|
return items, resp, nil
|
|
}
|
|
|
|
// ListUserProjectViewItems lists the items of a view in a user owned project.
|
|
//
|
|
// GitHub API docs: https://docs.github.com/rest/projects/items?apiVersion=2022-11-28#list-items-for-a-user-project-view
|
|
//
|
|
//meta:operation GET /users/{username}/projectsV2/{project_number}/views/{view_number}/items
|
|
func (s *ProjectsService) ListUserProjectViewItems(ctx context.Context, username string, projectNumber, viewNumber int, opts *ListProjectItemsOptions) ([]*ProjectV2Item, *Response, error) {
|
|
u := fmt.Sprintf("users/%v/projectsV2/%v/views/%v/items", username, projectNumber, viewNumber)
|
|
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 items []*ProjectV2Item
|
|
resp, err := s.client.Do(req, &items)
|
|
if err != nil {
|
|
return nil, resp, err
|
|
}
|
|
|
|
return items, resp, nil
|
|
}
|