Help us shape the future of Go! Take the 2026 Go Developer Survey

issues

package
v3.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 9, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package issues implements MCP tools for GitLab issue lifecycle operations.

The package covers project issue CRUD, listing, filtering, assignee and author queries, confidentiality, labels, milestones, due dates, state changes, and issue links to related tool domains such as notes, discussions, statistics, and work items. Handlers return typed MCP output structs and publish Markdown formatters for individual and meta-tool responses.

GitLab API References

The primary API backing this package is:

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ActionSpecs

func ActionSpecs(client *gitlabclient.Client) []toolutil.ActionSpec

ActionSpecs returns canonical specs for issue lifecycle actions exposed as MCP tools. The create, read, update, delete, reorder, move, subscribe, todo, and time-tracking routes are projected into the dynamic, meta, individual, and audit surfaces by the action catalog (ADR-0004).

func AuthorName

func AuthorName(i BasicOutput) string

AuthorName returns the issue author's display username for Markdown, read from the full author object. It is exported so sibling packages (e.g. mergerequests, search) that render issue rows of their own can show the author without reaching into the object. It takes BasicOutput because the author is what every entity that renders an issue carries, the basic one included.

func Delete

func Delete(ctx context.Context, client *gitlabclient.Client, input DeleteInput) error

Delete permanently removes an issue from a GitLab project. Returns an error if the issue does not exist or the user lacks permission.

func FormatListAllMarkdown

func FormatListAllMarkdown(out ListAllOutput) string

FormatListAllMarkdown renders a page of globally-scoped issues as a Markdown table. It is registered for ListAllOutput, the type the global action answers with, so this heading and these hints are what a reader of that action sees: while both list actions shared one output type, the registry had one key for the two of them and this formatter was never reached.

func FormatListGroupMarkdown

func FormatListGroupMarkdown(out ListGroupOutput) string

FormatListGroupMarkdown renders a page of a group's issues as a Markdown table, through the same renderer the project and global listings use.

func FormatListMarkdown

func FormatListMarkdown(out ListOutput) string

FormatListMarkdown renders a page of a project's issues as a Markdown table.

func FormatMarkdown

func FormatMarkdown(i Output) string

FormatMarkdown renders a single issue as the card of one object: its own fields, then the description as quoted prose under its label.

func FormatParticipantsMarkdown

func FormatParticipantsMarkdown(out ParticipantsOutput) string

FormatParticipantsMarkdown renders an issue's participants as a Markdown table: a collection of objects that share columns.

func FormatRelatedMRsMarkdown

func FormatRelatedMRsMarkdown(out RelatedMRsOutput, heading string) string

FormatRelatedMRsMarkdown renders the merge requests tied to an issue as a Markdown table.

func FormatTimeStatsMarkdown

func FormatTimeStatsMarkdown(ts TimeStatsOutput) string

FormatTimeStatsMarkdown renders an issue's time tracking as the card of one object: the two durations GitLab renders for a reader and the two counts of seconds they are computed from.

func FormatTodoMarkdown

func FormatTodoMarkdown(t TodoOutput) string

FormatTodoMarkdown renders a to-do item as the card of one object.

func GroupActionSpecs

func GroupActionSpecs(client *gitlabclient.Client) []toolutil.ActionSpec

GroupActionSpecs returns canonical specs for issue actions exposed through the group meta-tool surface. Currently scoped to group issue listing.

Types

type AddSpentTimeInput

type AddSpentTimeInput struct {
	ProjectID toolutil.StringOrInt `json:"project_id" jsonschema:"Project ID or URL-encoded path,required"`
	IssueIID  int64                `json:"issue_iid"  jsonschema:"Issue internal ID,required"`
	Duration  string               `json:"duration"   jsonschema:"Human-readable duration (e.g. 1h, 30m, 1w2d),required"`
	Summary   string               `json:"summary,omitempty" jsonschema:"Optional summary of work done"`
}

AddSpentTimeInput defines parameters for adding spent time to an issue.

type BasicOutput added in v3.1.0

type BasicOutput struct {
	toolutil.HintableOutput
	ID int64 `json:"id"`
	// IID is the issue's own project-scoped internal ID, mirroring the SDK
	// json key `iid`. Distinct from the global `id`.
	IID         int64    `` /* 161-byte string literal not displayed */
	Title       string   `json:"title"`
	Description string   `json:"description"`
	State       string   `json:"state"`
	Labels      []string `json:"labels"`
	// Author is the full author object mirrored from the SDK (1:1 fidelity).
	Author *toolutil.IssueUserOutput `json:"author,omitempty"`
	// Assignees is the list of full assignee objects mirrored from the SDK.
	Assignees []*toolutil.IssueUserOutput `json:"assignees"`
	// Assignee is the singular (deprecated upstream) assignee object.
	Assignee *toolutil.IssueUserOutput `json:"assignee,omitempty"`
	// Milestone is the full milestone object mirrored from the SDK.
	Milestone *toolutil.MRMilestoneOutput `json:"milestone,omitempty"`
	// ClosedBy is the full closer object mirrored from the SDK.
	ClosedBy          *toolutil.IssueUserOutput `json:"closed_by,omitempty"`
	WebURL            string                    `json:"web_url"`
	CreatedAt         string                    `json:"created_at"`
	UpdatedAt         string                    `json:"updated_at"`
	ClosedAt          string                    `json:"closed_at"`
	DueDate           string                    `json:"due_date"`
	Confidential      bool                      `json:"confidential"`
	DiscussionLocked  bool                      `json:"discussion_locked"`
	ProjectID         int64                     `json:"project_id"`
	Weight            int64                     `json:"weight,omitempty" tier:"premium"`
	IssueType         string                    `json:"issue_type,omitempty"`
	MergeRequestCount int64                     `json:"merge_requests_count,omitempty"`
	UserNotesCount    int64                     `json:"user_notes_count,omitempty"`
	Upvotes           int64                     `json:"upvotes,omitempty"`
	Downvotes         int64                     `json:"downvotes,omitempty"`
	// Additive 1:1 fields surfaced from the SDK Issue (full sub-objects and
	// scalars not previously exposed). Two of client-go's keys are not among
	// them. external_id is filled only from the string id of an external
	// tracker's issue, which no issues route and no search renders; the two
	// merge request listings that can return one list such an issue apart,
	// as the entity GitLab renders it. label_details is filled only where a
	// route takes with_labels_details, which search and those two listings
	// do not, so it sits on Output, whose routes do.
	TimeStats            *TimeStatsOutput                     `json:"time_stats,omitempty"`
	TaskCompletionStatus *toolutil.TaskCompletionStatusOutput `json:"task_completion_status,omitempty"`
	// What lib/api/entities/issue_basic.rb sends that client-go's Issue does
	// not model, read from the captured response (ADR-0021).
	// blocking_issues_count carries no tier: ee/lib/ee/api/entities/
	// issue_basic.rb exposes it under no licensed feature, so an Enterprise
	// build sends it licensed or not, and a Community one sends nothing.
	BlockingIssuesCount *int64 `json:"blocking_issues_count,omitempty"`
	StartDate           string `json:"start_date,omitempty"`
	Type                string `json:"type,omitempty"`
}

Output represents a GitLab issue.

func ToBasicOutput added in v3.1.0

func ToBasicOutput(issue *gl.Issue, extra toolutil.IssueBasicExtra) BasicOutput

ToOutput converts a GitLab API gl.Issue to the MCP tool output format, extracting author, milestone, assignees, and formatting timestamps as RFC 3339 strings. Nil labels are normalized to an empty slice.

func ToBasicOutputs added in v3.1.0

func ToBasicOutputs(list []*gl.Issue, captured *gitlabclient.ResponseCapture) ([]BasicOutput, error)

ToBasicOutputs converts a page of issues as API::Entities::IssueBasic renders them, one extra per issue in order. It is what a package outside this one calls when its own route presents the basic entity rather than the full issue: search, and the merge request's closed and related issues, which convert a whole page before setting an external tracker's rows apart.

type CreateInput

type CreateInput struct {
	// Basic metadata
	ProjectID   toolutil.StringOrInt `json:"project_id" jsonschema:"Project ID or URL-encoded path,required"`
	Title       string               `json:"title" jsonschema:"Issue title,required"`
	IID         int64                `` /* 143-byte string literal not displayed */
	Description string               `json:"description,omitempty" jsonschema:"Issue description (Markdown supported)"`
	IssueType   string               `json:"issue_type,omitempty" jsonschema:"Issue type (issue, incident, test_case, task)"`

	// Assignment and tracking
	AssigneeID  int64    `json:"assignee_id,omitempty" jsonschema:"Single user ID to assign (use assignee_ids for multiple)"`
	AssigneeIDs []int64  `json:"assignee_ids,omitempty" jsonschema:"User IDs to assign"`
	Labels      []string `json:"labels,omitempty" jsonschema:"Label names to apply"`
	MilestoneID int64    `json:"milestone_id,omitempty" jsonschema:"Milestone ID to associate"`
	EpicID      int64    `json:"epic_id,omitempty" tier:"premium" jsonschema:"Epic ID to associate the issue with"`
	Weight      int64    `json:"weight,omitempty" tier:"premium" jsonschema:"Issue weight, 0 or higher"`
	DueDate     string   `json:"due_date,omitempty" jsonschema:"Due date in YYYY-MM-DD format"`

	// Behavior flags
	Confidential *bool  `json:"confidential,omitempty" jsonschema:"Mark issue as confidential"`
	CreatedAt    string `json:"created_at,omitempty" jsonschema:"Creation date override (ISO 8601, requires admin permissions)"`

	// Discussion resolution
	MergeRequestToResolveDiscussionsOf int64  `json:"merge_request_to_resolve_discussions_of,omitempty" jsonschema:"MR IID whose unresolved discussions become issues"`
	DiscussionToResolve                string `json:"discussion_to_resolve,omitempty" jsonschema:"Discussion ID to mark as resolved by this issue"`
}

CreateInput defines parameters for creating a new issue.

type CreateTodoInput

type CreateTodoInput struct {
	ProjectID toolutil.StringOrInt `json:"project_id" jsonschema:"Project ID or URL-encoded path,required"`
	IssueIID  int64                `json:"issue_iid"  jsonschema:"Issue internal ID,required"`
}

CreateTodoInput defines parameters for creating a to-do for an issue.

type DeleteInput

type DeleteInput struct {
	ProjectID toolutil.StringOrInt `json:"project_id" jsonschema:"Project ID or URL-encoded path,required"`
	IssueIID  int64                `json:"issue_iid"  jsonschema:"Issue IID (project-scoped internal ID, not 'issue_id'),required"`
}

DeleteInput defines parameters for deleting an issue.

type GetByIDInput

type GetByIDInput struct {
	IssueID int64 `json:"issue_id" jsonschema:"The global issue ID (not the project-scoped IID),required"`
}

GetByIDInput defines parameters for retrieving an issue by its global ID.

type GetInput

type GetInput struct {
	ProjectID toolutil.StringOrInt `json:"project_id" jsonschema:"Project ID or URL-encoded path,required"`
	IssueIID  int64                `json:"issue_iid"  jsonschema:"Issue IID (project-scoped internal ID, not 'issue_id'),required"`
}

GetInput defines parameters for retrieving a single issue.

type IterationOutput

type IterationOutput struct {
	ID          int64  `json:"id"`
	IID         int64  `json:"iid"`
	Sequence    int64  `json:"sequence"`
	GroupID     int64  `json:"group_id"`
	Title       string `json:"title"`
	Description string `json:"description"`
	State       int64  `json:"state"`
	WebURL      string `json:"web_url"`
	CreatedAt   string `json:"created_at,omitempty"`
	UpdatedAt   string `json:"updated_at,omitempty"`
	StartDate   string `json:"start_date,omitempty"`
	DueDate     string `json:"due_date,omitempty"`
}

IterationOutput mirrors gl.GroupIteration.

type ListAllInput

type ListAllInput struct {
	State               string   `json:"state,omitempty"                jsonschema:"Filter by state (opened, closed, all)"`
	Labels              []string `json:"labels,omitempty"               jsonschema:"Label names to filter by"`
	NotLabels           []string `json:"not_labels,omitempty"           jsonschema:"Label names to exclude"`
	WithLabelsDetails   *bool    `json:"with_labels_details,omitempty"  jsonschema:"Return label objects with full details instead of just names"`
	Milestone           string   `json:"milestone,omitempty"            jsonschema:"Milestone title to filter by"`
	NotMilestone        string   `json:"not_milestone,omitempty"        jsonschema:"Milestone title to exclude"`
	Scope               string   `` /* 208-byte string literal not displayed */
	Search              string   `json:"search,omitempty"               jsonschema:"Search in title and description"`
	NotSearch           string   `json:"not_search,omitempty"           jsonschema:"Exclude issues matching this search text"`
	In                  string   `` /* 128-byte string literal not displayed */
	NotIn               string   `json:"not_in,omitempty"               jsonschema:"Fields the negated search query applies to (title, description)"`
	AssigneeID          *int64   `json:"assignee_id,omitempty"          jsonschema:"Filter by assignee user ID"`
	NotAssigneeID       []int64  `json:"not_assignee_id,omitempty"      jsonschema:"Exclude issues assigned to these user IDs"`
	AssigneeUsername    string   `json:"assignee_username,omitempty"    jsonschema:"Filter by assignee username"`
	NotAssigneeUsername string   `json:"not_assignee_username,omitempty" jsonschema:"Exclude issues assigned to this username"`
	AuthorID            *int64   `json:"author_id,omitempty"            jsonschema:"Filter by author user ID"`
	NotAuthorID         []int64  `json:"not_author_id,omitempty"        jsonschema:"Exclude issues authored by these user IDs"`
	AuthorUsername      string   `json:"author_username,omitempty"      jsonschema:"Filter by author username"`
	NotAuthorUsername   string   `json:"not_author_username,omitempty"  jsonschema:"Exclude issues authored by this username"`
	MyReactionEmoji     string   `json:"my_reaction_emoji,omitempty"    jsonschema:"Filter by issues you reacted to with this emoji (or None/Any)"`
	NotMyReactionEmoji  []string `json:"not_my_reaction_emoji,omitempty" jsonschema:"Exclude issues you reacted to with these emoji"`
	IIDs                []int64  `json:"iids,omitempty"                 jsonschema:"Filter by issue internal IDs"`
	IssueType           string   `json:"issue_type,omitempty"           jsonschema:"Filter by issue type (issue, incident, test_case, task)"`
	IterationID         *int64   `json:"iteration_id,omitempty"         tier:"premium" jsonschema:"Filter by iteration ID"`
	Confidential        *bool    `json:"confidential,omitempty"         jsonschema:"Filter by confidential status"`
	DueDate             string   `` /* 130-byte string literal not displayed */
	OrderBy             string   `` /* 180-byte string literal not displayed */
	Sort                string   `json:"sort,omitempty"                 jsonschema:"Sort direction (asc, desc)"`
	CreatedAfter        string   `json:"created_after,omitempty"        jsonschema:"Return issues created after date (ISO 8601)"`
	CreatedBefore       string   `json:"created_before,omitempty"       jsonschema:"Return issues created before date (ISO 8601)"`
	UpdatedAfter        string   `json:"updated_after,omitempty"        jsonschema:"Return issues updated after date (ISO 8601)"`
	UpdatedBefore       string   `json:"updated_before,omitempty"       jsonschema:"Return issues updated before date (ISO 8601)"`
	toolutil.PaginationInput
	toolutil.KeysetPaginationInput
}

ListAllInput defines parameters for GitLab's global issue list, GET /issues (no project scope), which answers only the issues the caller created unless Scope names another scope.

type ListAllOutput added in v3.1.0

type ListAllOutput ListOutput

ListAllOutput holds a page of issues from the global scope. It carries the same fields as ListOutput and exists to be a type of its own: the Markdown registry is keyed by the Go type, so while both list actions answered with one type only one formatter could be registered for the two of them, and the global listing rendered under the project listing's heading and hints, telling a reader to pass a project_id the action does not take.

func ListAll

func ListAll(ctx context.Context, client *gitlabclient.Client, input ListAllInput) (ListAllOutput, error)

ListAll retrieves a page of GitLab's global issue list. The scope is passed through as the caller wrote it, so an omitted one gets GitLab's default, created_by_me: the issues the caller created, not every issue it can see, which takes scope=all.

type ListGroupInput

type ListGroupInput struct {
	GroupID             toolutil.StringOrInt `json:"group_id"                       jsonschema:"Group ID or URL-encoded path,required"`
	State               string               `json:"state,omitempty"                jsonschema:"Filter by state (opened, closed, all)"`
	Labels              []string             `json:"labels,omitempty"               jsonschema:"Label names to filter by"`
	NotLabels           []string             `json:"not_labels,omitempty"           jsonschema:"Label names to exclude"`
	WithLabelsDetails   *bool                `json:"with_labels_details,omitempty"  jsonschema:"Return label objects with full details instead of just names"`
	Milestone           string               `json:"milestone,omitempty"            jsonschema:"Milestone title to filter by"`
	NotMilestone        string               `json:"not_milestone,omitempty"        jsonschema:"Milestone title to exclude"`
	Scope               string               `json:"scope,omitempty"                jsonschema:"Scope (created_by_me, assigned_to_me, all)"`
	Search              string               `json:"search,omitempty"               jsonschema:"Search in title and description"`
	NotSearch           string               `json:"not_search,omitempty"           jsonschema:"Exclude issues matching this search text"`
	In                  string               `` /* 128-byte string literal not displayed */
	NotIn               string               `json:"not_in,omitempty"               jsonschema:"Fields the negated search query applies to (title, description)"`
	AssigneeID          *int64               `json:"assignee_id,omitempty"          jsonschema:"Filter by assignee user ID"`
	NotAssigneeID       *int64               `json:"not_assignee_id,omitempty"      jsonschema:"Exclude issues assigned to this user ID"`
	AssigneeUsername    string               `json:"assignee_username,omitempty"    jsonschema:"Filter by assignee username"`
	NotAssigneeUsername string               `json:"not_assignee_username,omitempty" jsonschema:"Exclude issues assigned to this username"`
	AuthorID            *int64               `json:"author_id,omitempty"            jsonschema:"Filter by author user ID"`
	NotAuthorID         *int64               `json:"not_author_id,omitempty"        jsonschema:"Exclude issues authored by this user ID"`
	AuthorUsername      string               `json:"author_username,omitempty"      jsonschema:"Filter by author username"`
	NotAuthorUsername   string               `json:"not_author_username,omitempty"  jsonschema:"Exclude issues authored by this username"`
	MyReactionEmoji     string               `json:"my_reaction_emoji,omitempty"    jsonschema:"Filter by issues you reacted to with this emoji (or None/Any)"`
	NotMyReactionEmoji  string               `json:"not_my_reaction_emoji,omitempty" jsonschema:"Exclude issues you reacted to with this emoji"`
	IIDs                []int64              `json:"iids,omitempty"                 jsonschema:"Filter by issue internal IDs"`
	IssueType           string               `json:"issue_type,omitempty"           jsonschema:"Filter by issue type (issue, incident, test_case, task)"`
	IterationID         *int64               `json:"iteration_id,omitempty"         tier:"premium" jsonschema:"Filter by iteration ID"`
	Confidential        *bool                `json:"confidential,omitempty"         jsonschema:"Filter by confidential status"`
	DueDate             string               `` /* 130-byte string literal not displayed */
	OrderBy             string               `` /* 180-byte string literal not displayed */
	Sort                string               `json:"sort,omitempty"                 jsonschema:"Sort direction (asc, desc)"`
	CreatedAfter        string               `json:"created_after,omitempty"        jsonschema:"Return issues created after date (ISO 8601)"`
	CreatedBefore       string               `json:"created_before,omitempty"       jsonschema:"Return issues created before date (ISO 8601)"`
	UpdatedAfter        string               `json:"updated_after,omitempty"        jsonschema:"Return issues updated after date (ISO 8601)"`
	UpdatedBefore       string               `json:"updated_before,omitempty"       jsonschema:"Return issues updated before date (ISO 8601)"`
	toolutil.PaginationInput
	toolutil.KeysetPaginationInput
}

ListGroupInput defines parameters for listing issues across a group.

type ListGroupOutput

type ListGroupOutput struct {
	toolutil.HintableOutput
	Issues     []Output                  `json:"issues"`
	Pagination toolutil.PaginationOutput `json:"pagination"`
}

ListGroupOutput holds a paginated list of group issues.

func ListGroup

func ListGroup(ctx context.Context, client *gitlabclient.Client, input ListGroupInput) (ListGroupOutput, error)

ListGroup retrieves a paginated list of issues across all projects in a group.

type ListInput

type ListInput struct {
	ProjectID           toolutil.StringOrInt `json:"project_id"                     jsonschema:"Project ID or URL-encoded path,required"`
	State               string               `json:"state,omitempty"                jsonschema:"Filter by state (opened, closed, all)"`
	Labels              []string             `json:"labels,omitempty"               jsonschema:"Label names to filter by"`
	NotLabels           []string             `json:"not_labels,omitempty"           jsonschema:"Label names to exclude"`
	WithLabelsDetails   *bool                `` /* 142-byte string literal not displayed */
	Milestone           string               `json:"milestone,omitempty"            jsonschema:"Milestone title to filter by"`
	NotMilestone        string               `json:"not_milestone,omitempty"        jsonschema:"Milestone title to exclude"`
	Scope               string               `json:"scope,omitempty"                jsonschema:"Filter by scope (created_by_me, assigned_to_me, all)"`
	Search              string               `json:"search,omitempty"               jsonschema:"Search in title and description"`
	In                  string               `` /* 128-byte string literal not displayed */
	NotIn               string               `json:"not_in,omitempty"               jsonschema:"Fields the negated search query applies to (title, description)"`
	AssigneeID          *int64               `json:"assignee_id,omitempty"          jsonschema:"Filter by assignee user ID"`
	NotAssigneeID       *int64               `json:"not_assignee_id,omitempty"      jsonschema:"Exclude issues assigned to this user ID"`
	AssigneeUsername    string               `json:"assignee_username,omitempty"    jsonschema:"Filter by assignee username"`
	NotAssigneeUsername string               `json:"not_assignee_username,omitempty" jsonschema:"Exclude issues assigned to this username"`
	AuthorID            *int64               `json:"author_id,omitempty"            jsonschema:"Filter by author user ID"`
	NotAuthorID         *int64               `json:"not_author_id,omitempty"        jsonschema:"Exclude issues authored by this user ID"`
	AuthorUsername      string               `json:"author_username,omitempty"      jsonschema:"Filter by author username"`
	NotAuthorUsername   string               `json:"not_author_username,omitempty"  jsonschema:"Exclude issues authored by this username"`
	MyReactionEmoji     string               `` /* 127-byte string literal not displayed */
	NotMyReactionEmoji  string               `json:"not_my_reaction_emoji,omitempty" jsonschema:"Exclude issues you reacted to with this emoji"`
	IIDs                []int64              `json:"iids,omitempty"                 jsonschema:"Filter by issue internal IDs"`
	IssueType           string               `json:"issue_type,omitempty"           jsonschema:"Filter by issue type (issue, incident, test_case, task)"`
	IterationID         *int64               `json:"iteration_id,omitempty"         tier:"premium" jsonschema:"Filter by iteration ID"`
	Confidential        *bool                `json:"confidential,omitempty"         jsonschema:"Filter by confidential status"`
	DueDate             string               `` /* 142-byte string literal not displayed */
	CreatedAfter        string               `` /* 128-byte string literal not displayed */
	CreatedBefore       string               `` /* 129-byte string literal not displayed */
	UpdatedAfter        string               `` /* 128-byte string literal not displayed */
	UpdatedBefore       string               `` /* 129-byte string literal not displayed */
	OrderBy             string               `` /* 180-byte string literal not displayed */
	Sort                string               `json:"sort,omitempty"                 jsonschema:"Sort direction (asc, desc)"`
	toolutil.PaginationInput
	toolutil.KeysetPaginationInput
}

ListInput defines filters for listing project issues.

type ListMRsClosingInput

type ListMRsClosingInput struct {
	ProjectID toolutil.StringOrInt `json:"project_id"         jsonschema:"Project ID or URL-encoded path,required"`
	IssueIID  int64                `json:"issue_iid"          jsonschema:"Issue internal ID,required"`
	OrderBy   string               `json:"order_by,omitempty" jsonschema:"Column to order results by (e.g. created_at, updated_at)"`
	Sort      string               `json:"sort,omitempty"     jsonschema:"Sort direction (asc, desc)"`
	toolutil.PaginationInput
	toolutil.KeysetPaginationInput
}

ListMRsClosingInput defines parameters for listing MRs that close an issue on merge.

type ListMRsRelatedInput

type ListMRsRelatedInput struct {
	ProjectID toolutil.StringOrInt `json:"project_id"         jsonschema:"Project ID or URL-encoded path,required"`
	IssueIID  int64                `json:"issue_iid"          jsonschema:"Issue internal ID,required"`
	OrderBy   string               `json:"order_by,omitempty" jsonschema:"Column to order results by (e.g. created_at, updated_at)"`
	Sort      string               `json:"sort,omitempty"     jsonschema:"Sort direction (asc, desc)"`
	toolutil.PaginationInput
	toolutil.KeysetPaginationInput
}

ListMRsRelatedInput defines parameters for listing MRs related to an issue.

type ListOutput

type ListOutput struct {
	toolutil.HintableOutput
	Issues     []Output                  `json:"issues"`
	Pagination toolutil.PaginationOutput `json:"pagination"`
}

ListOutput holds a paginated list of issues.

func List

func List(ctx context.Context, client *gitlabclient.Client, input ListInput) (ListOutput, error)

List retrieves a paginated list of issues for a GitLab project. Supports filtering by state, labels, milestone, search text, assignee, author, negation filters, iteration, and sorting. Returns the issues with pagination metadata.

type MoveInput

type MoveInput struct {
	ProjectID   toolutil.StringOrInt `json:"project_id"     jsonschema:"Source project ID or URL-encoded path,required"`
	IssueIID    int64                `json:"issue_iid"      jsonschema:"Issue internal ID,required"`
	ToProjectID int64                `json:"to_project_id"  jsonschema:"Target project ID to move issue to,required"`
}

MoveInput defines parameters for moving an issue to another project.

type Output

type Output struct {
	BasicOutput
	HealthStatus       string                     `json:"health_status,omitempty" tier:"ultimate"`
	Subscribed         bool                       `json:"subscribed"`
	MovedToID          int64                      `json:"moved_to_id,omitempty"`
	EpicIssueID        int64                      `json:"epic_issue_id,omitempty" tier:"premium"`
	ServiceDeskReplyTo string                     `json:"service_desk_reply_to,omitempty"`
	References         *toolutil.ReferencesOutput `json:"references,omitempty"`
	Epic               *toolutil.EpicOutput       `json:"epic,omitempty" tier:"premium"`
	Iteration          *toolutil.IterationOutput  `json:"iteration,omitempty" tier:"premium"`
	Links              *toolutil.IssueLinksOutput `json:"_links,omitempty"`
	// LabelDetails is the labels array as label objects, which client-go's
	// Issue.UnmarshalJSON re-keys here when a route renders them that way:
	// only under with_labels_details, which the issue listings take.
	LabelDetails []*toolutil.LabelDetailsOutput `json:"label_details,omitempty"`
	// What only lib/api/entities/issue.rb adds, read from the captured
	// response (ADR-0021).
	EpicIID      *int64 `json:"epic_iid,omitempty" tier:"premium"`
	HasTasks     *bool  `json:"has_tasks,omitempty"`
	Imported     *bool  `json:"imported,omitempty"`
	ImportedFrom string `json:"imported_from,omitempty"`
	Severity     string `json:"severity,omitempty"`
	TaskStatus   string `json:"task_status,omitempty"`
}

Output is an issue as the fifteen routes of the issues API render it: API::Entities::Issue, which is the basic entity above plus what only a request through those routes carries.

The split is what lets each field sit where GitLab sends it. A search hit renders IssueBasic (lib/api/search.rb keys issues to it) and so does a merge request's closing issue, and those two used to be handed a type declaring an epic, an iteration, a health_status and five more keys their route cannot give them.

func Create

func Create(ctx context.Context, client *gitlabclient.Client, input CreateInput) (Output, error)

Create creates a new issue in the specified GitLab project. It maps all optional fields (description, labels, assignees, milestone, due date, confidential) to the GitLab API request. Returns the created issue or an error if the API call fails.

func Get

func Get(ctx context.Context, client *gitlabclient.Client, input GetInput) (Output, error)

Get retrieves a single issue by its internal ID from a GitLab project. Returns the issue details or an error if the issue is not found.

func GetByID

func GetByID(ctx context.Context, client *gitlabclient.Client, input GetByIDInput) (Output, error)

GetByID retrieves a single issue by its global numeric ID.

func Move

func Move(ctx context.Context, client *gitlabclient.Client, input MoveInput) (Output, error)

Move moves an issue from one project to another.

func Reorder

func Reorder(ctx context.Context, client *gitlabclient.Client, input ReorderInput) (Output, error)

Reorder changes the position of an issue relative to other issues.

func Subscribe

func Subscribe(ctx context.Context, client *gitlabclient.Client, input SubscribeInput) (Output, error)

Subscribe subscribes the authenticated user to an issue for notifications.

func ToOutput

func ToOutput(issue *gl.Issue, extra toolutil.IssueExtra) Output

ToOutput converts an issue as the issues API renders it: everything ToBasicOutput carries plus what only API::Entities::Issue adds.

func Unsubscribe

func Unsubscribe(ctx context.Context, client *gitlabclient.Client, input UnsubscribeInput) (Output, error)

Unsubscribe removes the authenticated user's subscription from an issue.

func Update

func Update(ctx context.Context, client *gitlabclient.Client, input UpdateInput) (Output, error)

Update modifies an existing issue in a GitLab project. Only non-zero fields in the input are applied. Supports changing title, description, state, assignees, labels (replace, add, remove), milestone, due date, and confidential flag. Returns the updated issue.

type ParticipantOutput

type ParticipantOutput struct {
	ID          int64  `json:"id"`
	Username    string `json:"username"`
	Name        string `json:"name"`
	State       string `json:"state,omitempty"`
	Locked      bool   `json:"locked"`
	PublicEmail string `json:"public_email,omitempty"`
	AvatarURL   string `json:"avatar_url,omitempty"`
	WebURL      string `json:"web_url"`
}

ParticipantOutput represents a participant in an issue: the whole of lib/api/entities/user_basic.rb, which GET /projects/:id/issues/:issue_iid/participants presents. locked and public_email are read from the captured response, since client-go decodes the participants into BasicUser, which models neither.

type ParticipantsInput added in v3.1.0

type ParticipantsInput struct {
	ProjectID toolutil.StringOrInt `json:"project_id" jsonschema:"Project ID or URL-encoded path,required"`
	IssueIID  int64                `json:"issue_iid"  jsonschema:"Issue IID (project-scoped internal ID, not 'issue_id'),required"`
	toolutil.PaginationInput
}

ParticipantsInput defines parameters for listing an issue's participants, and the page of them to list.

GitLab pages the list: the route presents paginate(participants), which reads page and per_page from the request whether or not the route declares them, and it declares neither. client-go's GetParticipants takes no options struct either, so the page travels as a request option.

type ParticipantsOutput

type ParticipantsOutput struct {
	toolutil.HintableOutput
	Participants []ParticipantOutput       `json:"participants"`
	Pagination   toolutil.PaginationOutput `json:"pagination"`
}

ParticipantsOutput holds one page of an issue's participants.

func GetParticipants

func GetParticipants(ctx context.Context, client *gitlabclient.Client, input ParticipantsInput) (ParticipantsOutput, error)

GetParticipants retrieves one page of the participants in an issue.

type RelatedMROutput

type RelatedMROutput struct {
	ID                          int64                                `json:"id"`
	IID                         int64                                `json:"iid"`
	ProjectID                   int64                                `json:"project_id"`
	Title                       string                               `json:"title"`
	State                       string                               `json:"state"`
	Description                 string                               `json:"description"`
	SourceBranch                string                               `json:"source_branch"`
	TargetBranch                string                               `json:"target_branch"`
	SourceProjectID             int64                                `json:"source_project_id"`
	TargetProjectID             int64                                `json:"target_project_id"`
	Author                      *toolutil.BasicUserOutput            `json:"author"`
	Assignee                    *toolutil.BasicUserOutput            `json:"assignee"`
	Assignees                   []*toolutil.BasicUserOutput          `json:"assignees"`
	Reviewers                   []*toolutil.BasicUserOutput          `json:"reviewers"`
	MergeUser                   *toolutil.BasicUserOutput            `json:"merge_user"`
	MergedBy                    *toolutil.BasicUserOutput            `json:"merged_by"`
	ClosedBy                    *toolutil.BasicUserOutput            `json:"closed_by"`
	Milestone                   *toolutil.MRMilestoneOutput          `json:"milestone"`
	Labels                      []string                             `json:"labels"`
	References                  *toolutil.ReferencesOutput           `json:"references"`
	TimeStats                   *TimeStatsOutput                     `json:"time_stats"`
	TaskCompletionStatus        *toolutil.TaskCompletionStatusOutput `json:"task_completion_status"`
	Draft                       bool                                 `json:"draft"`
	Imported                    bool                                 `json:"imported"`
	ImportedFrom                string                               `json:"imported_from"`
	DetailedMergeStatus         string                               `json:"detailed_merge_status"`
	MergeWhenPipelineSucceeds   bool                                 `json:"merge_when_pipeline_succeeds"`
	SHA                         string                               `json:"sha"`
	MergeCommitSHA              string                               `json:"merge_commit_sha"`
	SquashCommitSHA             string                               `json:"squash_commit_sha"`
	Squash                      bool                                 `json:"squash"`
	SquashOnMerge               bool                                 `json:"squash_on_merge"`
	ShouldRemoveSourceBranch    bool                                 `json:"should_remove_source_branch"`
	ForceRemoveSourceBranch     bool                                 `json:"force_remove_source_branch"`
	AllowCollaboration          bool                                 `json:"allow_collaboration"`
	AllowMaintainerToPush       bool                                 `json:"allow_maintainer_to_push"`
	DiscussionLocked            bool                                 `json:"discussion_locked"`
	HasConflicts                bool                                 `json:"has_conflicts"`
	BlockingDiscussionsResolved bool                                 `json:"blocking_discussions_resolved"`
	Upvotes                     int64                                `json:"upvotes"`
	Downvotes                   int64                                `json:"downvotes"`
	UserNotesCount              int64                                `json:"user_notes_count"`
	CreatedAt                   string                               `json:"created_at,omitempty"`
	UpdatedAt                   string                               `json:"updated_at,omitempty"`
	MergedAt                    string                               `json:"merged_at,omitempty"`
	MergeAfter                  string                               `json:"merge_after,omitempty"`
	PreparedAt                  string                               `json:"prepared_at,omitempty"`
	ClosedAt                    string                               `json:"closed_at,omitempty"`
	WebURL                      string                               `json:"web_url"`
	// The keys lib/api/entities/merge_request_basic.rb sends on every merge
	// request that client-go's BasicMergeRequest does not model, read from the
	// captured response (ADR-0021) and described on
	// [toolutil.MergeRequestExtra]. Its title_html and description_html are not
	// here: they wait on the render_html option, which neither the closed-by nor
	// the related-merge-requests route declares, so this response has never
	// carried them.
	ApprovalsBeforeMerge *int64 `json:"approvals_before_merge,omitempty" tier:"premium"`
	MergeStatus          string `json:"merge_status,omitempty"`
	Reference            string `json:"reference,omitempty"`
	WorkInProgress       bool   `json:"work_in_progress"`
}

RelatedMROutput mirrors gl.BasicMergeRequest, the merge-request object returned by the closing-MR and related-MR issue endpoints. Per the 1:1 audit policy it surfaces every SDK field with the correct type: user objects (author, assignee, assignees, reviewers, merge_user, merged_by, closed_by) are full *toolutil.BasicUserOutput/[]*toolutil.BasicUserOutput rather than flattened usernames, and milestone/references/time_stats/task_completion_status/ label_details are full nested objects reusing the issue sub-object shapes.

The canonical author key carries the full user object. The MR's own internal id is surfaced on iid (the BasicMergeRequest.iid field).

type RelatedMRsOutput

type RelatedMRsOutput struct {
	toolutil.HintableOutput
	MergeRequests []RelatedMROutput         `json:"merge_requests"`
	Pagination    toolutil.PaginationOutput `json:"pagination"`
}

RelatedMRsOutput holds a paginated list of merge requests related to an issue.

func ListMRsClosing

func ListMRsClosing(ctx context.Context, client *gitlabclient.Client, input ListMRsClosingInput) (RelatedMRsOutput, error)

ListMRsClosing retrieves merge requests that will close this issue on merge.

func ListMRsRelated

func ListMRsRelated(ctx context.Context, client *gitlabclient.Client, input ListMRsRelatedInput) (RelatedMRsOutput, error)

ListMRsRelated retrieves merge requests related to this issue.

type ReorderInput

type ReorderInput struct {
	ProjectID    toolutil.StringOrInt `json:"project_id"              jsonschema:"Project ID or URL-encoded path,required"`
	IssueIID     int64                `json:"issue_iid"               jsonschema:"Issue internal ID,required"`
	MoveAfterID  *int64               `json:"move_after_id,omitempty"  jsonschema:"ID of issue to position after"`
	MoveBeforeID *int64               `json:"move_before_id,omitempty" jsonschema:"ID of issue to position before"`
}

ReorderInput defines parameters for reordering an issue.

type SetTimeEstimateInput

type SetTimeEstimateInput struct {
	ProjectID toolutil.StringOrInt `json:"project_id" jsonschema:"Project ID or URL-encoded path,required"`
	IssueIID  int64                `json:"issue_iid"  jsonschema:"Issue internal ID,required"`
	Duration  string               `json:"duration"   jsonschema:"Human-readable duration (e.g. 3h30m, 1w2d),required"`
}

SetTimeEstimateInput defines parameters for setting a time estimate on an issue.

type SubscribeInput

type SubscribeInput struct {
	ProjectID toolutil.StringOrInt `json:"project_id" jsonschema:"Project ID or URL-encoded path,required"`
	IssueIID  int64                `json:"issue_iid"  jsonschema:"Issue internal ID,required"`
}

SubscribeInput defines parameters for subscribing to an issue.

type TimeStatsOutput

type TimeStatsOutput struct {
	toolutil.HintableOutput
	HumanTimeEstimate   string `json:"human_time_estimate"`
	HumanTotalTimeSpent string `json:"human_total_time_spent"`
	TimeEstimate        int64  `json:"time_estimate"`
	TotalTimeSpent      int64  `json:"total_time_spent"`
}

TimeStatsOutput represents time tracking statistics for an issue.

func AddSpentTime

func AddSpentTime(ctx context.Context, client *gitlabclient.Client, input AddSpentTimeInput) (TimeStatsOutput, error)

AddSpentTime adds spent time for an issue.

func GetTimeStats

func GetTimeStats(ctx context.Context, client *gitlabclient.Client, input GetInput) (TimeStatsOutput, error)

GetTimeStats retrieves total time tracking statistics for an issue.

func ResetSpentTime

func ResetSpentTime(ctx context.Context, client *gitlabclient.Client, input GetInput) (TimeStatsOutput, error)

ResetSpentTime resets the total spent time for an issue.

func ResetTimeEstimate

func ResetTimeEstimate(ctx context.Context, client *gitlabclient.Client, input GetInput) (TimeStatsOutput, error)

ResetTimeEstimate resets the time estimate for an issue back to zero.

func SetTimeEstimate

func SetTimeEstimate(ctx context.Context, client *gitlabclient.Client, input SetTimeEstimateInput) (TimeStatsOutput, error)

SetTimeEstimate sets the time estimate for an issue.

type TodoOutput

type TodoOutput struct {
	toolutil.HintableOutput
	ID          int64                     `json:"id"`
	ActionName  string                    `json:"action_name"`
	TargetType  string                    `json:"target_type"`
	TargetTitle string                    `json:"target_title"`
	TargetURL   string                    `json:"target_url"`
	Author      *toolutil.UserBasicOutput `json:"author,omitempty"`
	Body        string                    `json:"body,omitempty"`
	State       string                    `json:"state"`
	CreatedAt   string                    `json:"created_at,omitempty"`
	UpdatedAt   string                    `json:"updated_at,omitempty"`
}

TodoOutput represents a to-do item created from an issue.

POST /projects/:id/issues/:issue_iid/todo presents lib/api/entities/todo.rb. The to-do carries its own keys, its author and the instant it last changed; the issue it points at is the one the caller named, kept here as its title and URL, and the project it belongs to is the one the caller named too, so both are left to issue.get and project.get rather than repeated on a confirmation. A to-do raised on a project's issue belongs to no group, so the entity's group is never sent on this route.

func CreateTodo

func CreateTodo(ctx context.Context, client *gitlabclient.Client, input CreateTodoInput) (TodoOutput, error)

CreateTodo creates a to-do item for the authenticated user on the specified issue.

GitLab answers 304 Not Modified, with no body, when the caller already has a pending to-do on the issue. client-go does not treat that status as an error and then fails to decode the empty body, which used to reach the caller as a bare end-of-input error; it is reported as the pending to-do it is.

type UnsubscribeInput

type UnsubscribeInput struct {
	ProjectID toolutil.StringOrInt `json:"project_id" jsonschema:"Project ID or URL-encoded path,required"`
	IssueIID  int64                `json:"issue_iid"  jsonschema:"Issue internal ID,required"`
}

UnsubscribeInput defines parameters for unsubscribing from an issue.

type UpdateInput

type UpdateInput struct {
	ProjectID        toolutil.StringOrInt `json:"project_id"              jsonschema:"Project ID or URL-encoded path,required"`
	IssueIID         int64                `json:"issue_iid"               jsonschema:"Issue IID (project-scoped internal ID, not 'issue_id'),required"`
	Title            string               `json:"title,omitempty"         jsonschema:"New title"`
	Description      string               `json:"description,omitempty"   jsonschema:"New description (Markdown supported)"`
	StateEvent       string               `json:"state_event,omitempty"   jsonschema:"State transition (close, reopen)"`
	AssigneeID       int64                `json:"assignee_id,omitempty"       jsonschema:"Single user ID to assign (use assignee_ids for multiple)"`
	AssigneeIDs      []int64              `json:"assignee_ids,omitempty"  jsonschema:"New assignee user IDs"`
	Labels           []string             `json:"labels,omitempty"        jsonschema:"Label names to replace all existing"`
	AddLabels        []string             `json:"add_labels,omitempty"    jsonschema:"Label names to add without removing existing"`
	RemoveLabels     []string             `json:"remove_labels,omitempty" jsonschema:"Label names to remove"`
	EpicID           int64                `json:"epic_id,omitempty"       tier:"premium" jsonschema:"Epic ID to associate"`
	MilestoneID      *int64               `json:"milestone_id,omitempty"  jsonschema:"New milestone ID (0 to unset. Omit to leave unchanged)"`
	DueDate          string               `json:"due_date,omitempty"      jsonschema:"New due date in YYYY-MM-DD format"`
	Confidential     *bool                `json:"confidential,omitempty"  jsonschema:"Update confidential flag"`
	IssueType        string               `json:"issue_type,omitempty"    jsonschema:"Issue type (issue, incident, test_case, task)"`
	Weight           int64                `json:"weight,omitempty"        tier:"premium" jsonschema:"Issue weight, 0 or higher"`
	DiscussionLocked *bool                `json:"discussion_locked,omitempty" jsonschema:"Lock discussions on this issue"`
	UpdatedAt        string               `json:"updated_at,omitempty"    jsonschema:"Update timestamp override (ISO 8601/RFC 3339, requires admin permissions)"`
}

UpdateInput defines parameters for updating an existing issue.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL