Documentation
¶
Overview ¶
Package client implements the Jira Cloud HTTP transport for gojira.
It handles Basic authentication (email:token base64-encoded), request construction, 429 rate-limit retry with Retry-After / exponential backoff, transient network-error retry, and typed sentinel errors for callers.
The package knows nothing about issues, ADF, links, Markdown, or crawling. Its only project-internal import is internal/config.
Index ¶
- Variables
- func RenderCreateBody(project, issueType string, opts ...CreateOption) ([]byte, error)
- func RenderUpdateBody(opts ...UpdateOption) ([]byte, error)
- type APIError
- type Client
- func (c *Client) AddComment(ctx context.Context, key string, opts ...CommentOption) (Comment, error)
- func (c *Client) CreateIssue(ctx context.Context, project, issueType string, opts ...CreateOption) (CreatedIssue, error)
- func (c *Client) DevStatus(ctx context.Context, issueNumericID, application, dataType string) (DevStatusResponse, error)
- func (c *Client) GetIssue(ctx context.Context, key string, expand []string) ([]byte, error)
- func (c *Client) ListFields(ctx context.Context) ([]Field, error)
- func (c *Client) ListTransitions(ctx context.Context, key string) ([]Transition, error)
- func (c *Client) Search(ctx context.Context, jql string, maxResults int) (SearchResult, error)
- func (c *Client) TransitionIssue(ctx context.Context, key, transitionID string, opts ...TransitionOption) error
- func (c *Client) UpdateIssue(ctx context.Context, key string, opts ...UpdateOption) error
- type Comment
- type CommentOption
- type CreateOption
- func WithAssigneeAccountID(id string) CreateOption
- func WithDescriptionADF(doc json.RawMessage) CreateOption
- func WithDescriptionText(text string) CreateOption
- func WithField(fieldID string, value any) CreateOption
- func WithLabels(labels ...string) CreateOption
- func WithParent(key string) CreateOption
- func WithRawFields(m map[string]any) CreateOption
- func WithSummary(s string) CreateOption
- type CreatedIssue
- type DevStatusBranch
- type DevStatusBranchEntry
- type DevStatusBuild
- type DevStatusBuildRef
- type DevStatusCommit
- type DevStatusCommitRef
- type DevStatusInstance
- type DevStatusInstanceMeta
- type DevStatusPR
- type DevStatusPerson
- type DevStatusRepoRef
- type DevStatusRepository
- type DevStatusResponse
- type DevStatusReviewer
- type DevStatusTestSummary
- type Field
- type Option
- func WithHTTPClient(hc *http.Client) Option
- func WithLogger(lg *slog.Logger) Option
- func WithMaxRetries(n int) Option
- func WithNetworkBackoff(base, max time.Duration) Option
- func WithRateLimitBackoff(base, max time.Duration) Option
- func WithRoundTripper(rt http.RoundTripper) Option
- func WithUserAgent(ua string) Option
- type SearchResult
- type Transition
- type TransitionOption
- type UpdateOption
- func WithAssigneeAccountIDUpdate(id string) UpdateOption
- func WithDescriptionADFUpdate(doc json.RawMessage) UpdateOption
- func WithDescriptionTextUpdate(text string) UpdateOption
- func WithFieldUpdate(fieldID string, value any) UpdateOption
- func WithLabelsUpdate(labels ...string) UpdateOption
- func WithRawFieldsUpdate(m map[string]any) UpdateOption
- func WithSummaryUpdate(s string) UpdateOption
- func WithUpdateVerb(fieldID, verb string, value any) UpdateOption
Constants ¶
This section is empty.
Variables ¶
var ( // This is a total-failure condition: credentials are invalid. ErrUnauthorized = errors.New("client: unauthorized (401)") // ErrForbidden is returned when the server responds with 403. // The caller should render a permission-denied stub and continue. ErrForbidden = errors.New("client: forbidden (403)") // ErrNotFound is returned when the server responds with 404. // The caller should render a not-found stub and continue. ErrNotFound = errors.New("client: not found (404)") // ErrRateLimited is returned when the server responds with 429 and // all retry attempts are exhausted. ErrRateLimited = errors.New("client: rate limited (429) after retries") // ErrBadRequest is returned when the server responds with 400. The // returned error may be a *APIError carrying Jira's per-field error // details (see phase-a-transport-2); callers can still match it with // errors.Is(err, ErrBadRequest). ErrBadRequest = errors.New("client: bad request (400)") // ErrConflict is returned when the server responds with 409, e.g. an // invalid workflow transition. ErrConflict = errors.New("client: conflict (409)") )
Sentinel errors that callers can match with errors.Is.
Functions ¶
func RenderCreateBody ¶
func RenderCreateBody(project, issueType string, opts ...CreateOption) ([]byte, error)
RenderCreateBody assembles the JSON body for Client.CreateIssue from the required project key + issuetype name plus zero or more options. It is exported so the gojira facade can offer a dry-run affordance (build-without-send) reusing exactly the same assembly path the real CreateIssue method will use.
func RenderUpdateBody ¶
func RenderUpdateBody(opts ...UpdateOption) ([]byte, error)
RenderUpdateBody assembles the JSON body for Client.UpdateIssue from zero or more options. With no options the result is "{}" — a no-op edit that Jira accepts without complaint, rather than the malformed {"fields":{}} that some servers reject.
Types ¶
type APIError ¶
type APIError struct {
// Status is the HTTP status code that produced this error (400 or 409
// for Jira REST v3 in the current client).
Status int
// Messages are the top-level "errorMessages" entries from the Jira
// response body. nil/empty when the body had none.
Messages []string
// FieldErrors maps a Jira field id (e.g. "summary",
// "customfield_10010") to its per-field validation message. nil/empty
// when the body had no "errors" object.
FieldErrors map[string]string
// contains filtered or unexported fields
}
APIError is a structured representation of a Jira REST API error response, returned for 400 (Bad Request) and 409 (Conflict) statuses. It wraps the matching sentinel (ErrBadRequest or ErrConflict) so callers can both classify the failure with errors.Is and inspect which specific fields the server rejected via errors.As.
Jira Cloud v3 returns errors in the shape
{"errorMessages": ["..."], "errors": {"summary": "...", "...": "..."}}
Either key may be absent. When the body is empty, not JSON, or shaped differently, [parseAPIError] still returns an *APIError carrying only the status and the sentinel — degrading gracefully so classification is never lost.
func (*APIError) Error ¶
Error implements the error interface. The returned string is stable for a given *APIError value: field-error keys are sorted alphabetically so message text does not depend on Go's map iteration order, which keeps log lines and test assertions reproducible.
Shape (omitted sections are dropped):
"client: bad request (400): <message1>; <message2> [field1=msg; field2=msg]"
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is the Jira Cloud HTTP transport. Construct via New. The zero value is not valid.
func New ¶
New constructs a Client from cfg and applies any provided options.
It validates cfg.Site as a parseable URL with a non-empty host and pre-computes the Basic auth header. Returns an error if cfg.Site is not a valid URL.
func (*Client) AddComment ¶
func (c *Client) AddComment(ctx context.Context, key string, opts ...CommentOption) (Comment, error)
AddComment appends a comment to an existing Jira issue. When no option supplies a body the default is an empty ADF paragraph; Jira accepts this as a deliberately empty comment.
func (*Client) CreateIssue ¶
func (c *Client) CreateIssue(ctx context.Context, project, issueType string, opts ...CreateOption) (CreatedIssue, error)
CreateIssue creates a new Jira issue. The project key and issue-type name are required and explicit (signature-honesty: behavior-affecting inputs are not hidden in options). Everything else — summary, description, assignee, labels, parent, custom fields — is supplied via the CreateOption functional-option set in fields.go, so adding a new Jira field will not widen this signature.
On success Jira returns 201 with {id, key, self}; the parsed struct is returned. On 400/409 the error is an *APIError that still satisfies errors.Is against ErrBadRequest / ErrConflict via Unwrap.
func (*Client) DevStatus ¶
func (c *Client) DevStatus(ctx context.Context, issueNumericID, application, dataType string) (DevStatusResponse, error)
DevStatus fetches the development metadata (pull requests, branches, commits, repositories, builds — depending on dataType) that Jira surfaces in its UI Development panel for the issue identified by its numeric ID.
GET <site>/rest/dev-status/1.0/issue/detail
?issueId=<numeric>&applicationType=<application>&dataType=<dataType>
# Important: this endpoint is NOT in the documented Jira Cloud platform REST API
The /rest/dev-status/1.0 path is not part of the platform OpenAPI specification at developer.atlassian.com. It is the same endpoint Atlassian's own Jira UI consumes to populate the Development panel on every issue page; it has been stable for over a decade for that reason. gojira treats it as best-effort enrichment: callers can opt out cleanly by setting GOJIRA_INCLUDE_DEV_STATUS=false (handled at the devstatus enricher and crawl orchestrator layers), in which case this method is never invoked.
429, 401, 403, 404, and transient network errors are handled identically to Client.GetIssue, using the same retry/backoff machinery and propagating the same typed sentinel errors.
issueNumericID must be the numeric issue id (the top-level "id" field of the standard GET /issue/<KEY> response, e.g. "86679"). The endpoint silently returns an empty detail array for issue *keys* — passing the human-readable key by mistake therefore looks like "no entities" rather than an error. application is the upstream applicationType value (e.g. "GitHub", "Bitbucket", "GitLab", "GitHubEnterprise"); the caller is expected to fan out one call per configured application.
dataType selects which entity list the response will populate. Valid values mirror the Jira UI Development panel groupings:
- "pullrequest" populates DevStatusInstance.PullRequests
- "branch" populates DevStatusInstance.Branches
- "commit" populates DevStatusInstance.Commits
- "repository" populates DevStatusInstance.Repositories
- "build" populates DevStatusInstance.Builds
The endpoint accepts any string and silently returns an empty detail for unrecognised values; callers (the devstatus enricher in production) restrict dataType to the configured set.
func (*Client) GetIssue ¶
GetIssue fetches the raw JSON body for the Jira issue identified by key from the configured site's REST API v3 endpoint:
GET <site>/rest/api/3/issue/<key>[?expand=<csv>]
On success it returns the raw response bytes. On failure it returns one of the typed sentinel errors (ErrUnauthorized, ErrForbidden, ErrNotFound, ErrRateLimited) or a wrapped error containing the HTTP status code.
429 responses are retried up to maxRateLimitRetries times, honouring the Retry-After header when present. Transient network errors (timeouts and mid-stream io.EOF) are retried up to maxNetworkRetries times. Context cancellation is respected throughout.
expand is the list of Jira expansion tokens to pass via the `expand` query parameter (e.g. []string{"names"} to receive the top-level "names" object mapping every field ID, including customfield_*, to its human-readable label). The values are comma-joined into a single `expand=<a>,<b>,...` query parameter exactly as documented at https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issues/#api-rest-api-3-issue-issueidorkey-get. When expand is empty or nil, no `expand` query parameter is sent and the response shape matches the pre-expansion behaviour.
expand is a parameter rather than a hard-coded default inside the body: callers know what they want from the response, and embedding a "blessed" value here would violate the project's signature-honesty rule (see docs/engineering-principles.md). Internal callers that want human-readable custom-field labels pass []string{"names"} explicitly; callers that want the legacy shape pass nil.
func (*Client) ListFields ¶
ListFields fetches the tenant's field metadata from:
GET <site>/rest/api/3/field
It is used by the hierarchy discoverer to auto-detect the Epic Link custom field ID, which varies per tenant. 429 and transient network errors are retried using the same machinery as GetIssue.
func (*Client) ListTransitions ¶
ListTransitions fetches the workflow transitions currently available for the issue identified by key. The list is workflow-state dependent: Jira only returns transitions whose preconditions are met for the current state.
func (*Client) Search ¶
Search executes a JQL query against the modern Jira Cloud search endpoint:
POST <site>/rest/api/3/search/jql
{"jql": "...", "fields": ["key"], "maxResults": N}
Only the issue keys from the response are returned; the rest of each issue payload is discarded. This is sufficient for hierarchy discovery, which only needs keys to feed back into the crawl queue.
429, 401, 403, 404, and transient network errors are handled identically to GetIssue, using the same retry/backoff machinery.
maxResults caps the maxResults parameter sent in the request body. When maxResults <= 0, the Jira API default is used (currently 50).
Pagination limitation (v0.1) ¶
The modern endpoint uses cursor-based pagination via nextPageToken. Search currently returns only the first page (up to maxResults results) and surfaces NextPageToken on SearchResult so callers can detect when more results exist. Automatic multi-page aggregation is deferred to post-MVP.
func (*Client) TransitionIssue ¶
func (c *Client) TransitionIssue(ctx context.Context, key, transitionID string, opts ...TransitionOption) error
TransitionIssue moves an issue through the given workflow transition (identified by Jira's tenant/workflow-specific transition id). Options allow setting fields or appending a comment during the transition. Jira responds with 204 on success.
func (*Client) UpdateIssue ¶
UpdateIssue edits fields on an existing Jira issue identified by key. Field selection mirrors [CreateIssue] via the UpdateOption set, which shares the underlying builder so options stay in lockstep. Jira responds with 204 No Content on success; the method therefore returns no value beyond the error.
type Comment ¶
Comment is the response payload from a successful Client.AddComment call, carrying the Jira-assigned id, author identity, and creation timestamp (left as the raw ISO-8601 string Jira returns).
type CommentOption ¶
type CommentOption func(*commentBody)
CommentOption customizes an Client.AddComment request body. The body is always an ADF document; WithCommentText converts plain text, while WithCommentADF lets callers supply a rich pre-built document.
func WithCommentADF ¶
func WithCommentADF(doc json.RawMessage) CommentOption
WithCommentADF sets the comment body from a caller-supplied ADF document. Use this for rich-text content (lists, code blocks, links) the plain-text helper cannot express.
func WithCommentText ¶
func WithCommentText(text string) CommentOption
WithCommentText sets the comment body from plain text, converting it to ADF via adf.BuildParagraphDoc.
type CreateOption ¶
type CreateOption func(*fieldsBuilder)
CreateOption customizes a CreateIssue request body. It is shaped as a function over the internal builder so each option stays a tiny, independently-testable unit and new options can be added with zero disruption to existing call sites.
func WithAssigneeAccountID ¶
func WithAssigneeAccountID(id string) CreateOption
WithAssigneeAccountID sets the assignee on a Create request by Atlassian accountId — the only assignee write form Jira Cloud supports since the 2019 GDPR migration.
func WithDescriptionADF ¶
func WithDescriptionADF(doc json.RawMessage) CreateOption
WithDescriptionADF sets the issue description from a caller-supplied ADF document on a Create request. Use this when you already have rich ADF (lists, code blocks, etc.) you do not want to re-parse from text.
func WithDescriptionText ¶
func WithDescriptionText(text string) CreateOption
WithDescriptionText sets the issue description from plain text on a Create request. The text is converted to ADF via adf.BuildParagraphDoc so Jira accepts it.
func WithField ¶
func WithField(fieldID string, value any) CreateOption
WithField is the generic escape hatch: set fields[fieldID]=value with no typed wrapper. Use this for any custom field or for fields the typed options above do not cover. This is the seam that lets gojira support a new Jira field with ZERO signature churn.
func WithLabels ¶
func WithLabels(labels ...string) CreateOption
WithLabels sets the labels array on a Create request.
func WithParent ¶
func WithParent(key string) CreateOption
WithParent sets the parent issue key on a Create request (e.g. a Sub-task's parent). Update has its own "parent" semantics that differ per workflow; we therefore expose WithParent only on Create.
func WithRawFields ¶
func WithRawFields(m map[string]any) CreateOption
WithRawFields merges a caller-supplied map of fieldID→value into the fields object. Useful when the gRPC layer hands in a bulk map of custom-field overrides. Conflicts with earlier typed options resolve last-write-wins.
func WithSummary ¶
func WithSummary(s string) CreateOption
WithSummary sets the issue summary on a Create request.
type CreatedIssue ¶
CreatedIssue is the response payload from a successful Client.CreateIssue call. Self is the canonical REST URL Jira returns for the new issue.
type DevStatusBranch ¶
DevStatusBranch holds a branch reference from a Dev Status PR entry (the source/destination "branch" field of a pull request). It is a distinct type from DevStatusBranchEntry which represents a top- level entry returned by a dataType=branch query.
type DevStatusBranchEntry ¶
type DevStatusBranchEntry struct {
Name string `json:"name"`
URL string `json:"url"`
CreatePullRequestURL string `json:"createPullRequestUrl"`
Repository DevStatusRepoRef `json:"repository"`
LastCommit DevStatusCommitRef `json:"lastCommit"`
}
DevStatusBranchEntry is a single entry returned by a Dev Status query for dataType=branch. The Jira UI surfaces these in the Development panel alongside pull requests and commits; gojira mirrors that grouping in its Markdown output.
type DevStatusBuild ¶
type DevStatusBuild struct {
ID string `json:"id"`
BuildNumber int `json:"buildNumber"`
Name string `json:"name"`
Description string `json:"description"`
URL string `json:"url"`
State string `json:"state"`
LastUpdated string `json:"lastUpdated"`
TestSummary *DevStatusTestSummary `json:"testSummary,omitempty"`
References []DevStatusBuildRef `json:"references"`
}
DevStatusBuild is a single entry returned by a Dev Status query for dataType=build. State is the upstream lifecycle string ("SUCCESSFUL", "FAILED", "IN_PROGRESS", "STOPPED", "PENDING", ...); gojira does not normalise it. TestSummary is a pointer so a build that does not report test counts can be distinguished from one that reports zero.
type DevStatusBuildRef ¶
DevStatusBuildRef is a single git reference (branch or tag) tied to a build. Jira surfaces it so the build can be attributed to the branch its CI ran on.
type DevStatusCommit ¶
type DevStatusCommit struct {
ID string `json:"id"`
DisplayID string `json:"displayId"`
URL string `json:"url"`
Message string `json:"message"`
Author DevStatusPerson `json:"author"`
AuthorTimestamp string `json:"authorTimestamp"`
FileCount int `json:"fileCount"`
Merge bool `json:"merge"`
Repository DevStatusRepoRef `json:"repository"`
}
DevStatusCommit is a single entry returned by a Dev Status query for dataType=commit. Fields mirror the upstream response exactly; gojira preserves the full SHA in ID and the seven-character abbreviation in DisplayID rather than re-deriving the latter, in case future Jira versions change the abbreviation length.
type DevStatusCommitRef ¶
type DevStatusCommitRef struct {
ID string `json:"id"`
DisplayID string `json:"displayId"`
URL string `json:"url"`
Message string `json:"message"`
Author DevStatusPerson `json:"author"`
AuthorTimestamp string `json:"authorTimestamp"`
}
DevStatusCommitRef is the last-commit pointer embedded inside a Dev Status branch entry. It mirrors the same fields as DevStatusCommit but without the standalone-entity fields (fileCount, merge, repository) that only appear on a top-level commit query.
type DevStatusInstance ¶
type DevStatusInstance struct {
Instance DevStatusInstanceMeta `json:"_instance"`
PullRequests []DevStatusPR `json:"pullRequests"`
Branches []DevStatusBranchEntry `json:"branches"`
Commits []DevStatusCommit `json:"commits"`
Repositories []DevStatusRepository `json:"repositories"`
Builds []DevStatusBuild `json:"builds"`
}
DevStatusInstance groups the development entities returned by a single development-tool integration (e.g. one connected GitHub app).
Exactly one of the entity lists is non-empty for a given response, depending on the dataType the caller requested. The struct unmarshals all five tolerantly so a single Go type can carry the response for any dataType the Client.DevStatus caller asked for.
type DevStatusInstanceMeta ¶
type DevStatusInstanceMeta struct {
Type string `json:"type"`
Name string `json:"name"`
BaseURL string `json:"baseUrl"`
}
DevStatusInstanceMeta describes the development-tool integration that owns a DevStatusInstance's entries.
type DevStatusPR ¶
type DevStatusPR struct {
ID string `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Status string `json:"status"`
LastUpdate string `json:"lastUpdate"`
Source DevStatusBranch `json:"source"`
Destination DevStatusBranch `json:"destination"`
Author DevStatusPerson `json:"author"`
Reviewers []DevStatusReviewer `json:"reviewers"`
Repository string `json:"repositoryName"`
RepositoryURL string `json:"repositoryUrl"`
CommentCount int `json:"commentCount"`
}
DevStatusPR is a single pull-request entry returned by the Dev Status endpoint. Field names match Jira's response shape exactly; semantic translation (e.g. mapping Name → Title) happens in the devstatus package, not here.
type DevStatusPerson ¶
type DevStatusPerson struct {
Name string `json:"name"`
}
DevStatusPerson holds the author of a Dev Status PR/commit/branch entry. The Jira response also carries an "avatar" URL, which gojira does not consume.
type DevStatusRepoRef ¶
DevStatusRepoRef is the small repository pointer embedded inside other Dev Status entities (branches, commits). The Jira response nests a {"name", "url"} pair; gojira preserves both so the renderer can label the parent entity with its repository.
type DevStatusRepository ¶
type DevStatusRepository struct {
Name string `json:"name"`
URL string `json:"url"`
Avatar string `json:"avatar"`
}
DevStatusRepository is a single entry returned by a Dev Status query for dataType=repository. The Jira UI surfaces these so users can see which repositories have referenced an issue even when no PR or branch carries the issue key directly.
The upstream response also nests truncated commits[] and branches[] arrays inside each repository entry; gojira does not consume them (they are sparser than the top-level dataType=commit/branch queries and would risk duplication if rendered separately).
type DevStatusResponse ¶
type DevStatusResponse struct {
Errors []json.RawMessage `json:"errors"`
Detail []DevStatusInstance `json:"detail"`
}
DevStatusResponse is the parsed shape of a successful Dev Status API response. The endpoint returns a single envelope for any of the five supported dataType values (pullrequest, branch, commit, repository, build); the per-entity list inside each DevStatusInstance differs per dataType. A query for dataType=branch populates Branches and leaves PullRequests/Commits/Repositories/Builds empty, and so on.
Errors is the upstream response's "errors" array. A non-empty Errors slice does not by itself cause Client.DevStatus to return a Go error: the server returns HTTP 200 with embedded soft-error entries (e.g. when one connected GitHub instance is unreachable while another succeeded). Callers decide how to surface these.
The element type is intentionally json.RawMessage rather than a typed struct. The Dev Status endpoint is undocumented and the per-error entry shape is not guaranteed stable: production responses have been observed carrying both string entries (older tenants) and JSON objects with shape `{"code": <int>, "message": <string>, "userId": <string>, ...}` (newer tenants — observed on PROJ-1417 for dataType=commit and dataType=build). Modelling Errors as a typed slice against a single observed shape would break the unmarshal as soon as the other shape appears. json.RawMessage accepts any valid JSON element and lets the (rare) caller that wants to introspect the entries decode each one lazily. This is the "signature honesty" rule from docs/engineering-principles.md applied to response models: do not pretend to know a shape we have not verified across the entire observed input space.
type DevStatusReviewer ¶
DevStatusReviewer holds a single reviewer entry from a Dev Status PR.
type DevStatusTestSummary ¶
type DevStatusTestSummary struct {
TotalNumber int `json:"totalNumber"`
PassedNumber int `json:"passedNumber"`
FailedNumber int `json:"failedNumber"`
SkippedNumber int `json:"skippedNumber"`
}
DevStatusTestSummary holds the per-build test counts surfaced by Dev Status for CI integrations that publish them (Bitbucket Pipelines, GitHub Actions via the Atlassian app, etc.). Fields with no value default to zero.
type Field ¶
Field is the subset of Jira field metadata that gojira needs. It mirrors the relevant fields in the GET /rest/api/3/field response:
[{"id": "...", "key": "...", "name": "...", "custom": true|false, ...}]
Only ID, Key, Name, and Custom are populated; everything else is dropped.
type Option ¶
type Option func(*Client)
Option is a functional option for New.
func WithHTTPClient ¶
WithHTTPClient replaces the entire http.Client used for requests. Useful in tests that inject an httptest.Server-backed client.
func WithLogger ¶
WithLogger installs a logging RoundTripper that emits one INFO summary per request (method/url/status/duration_ms/bytes) and, when the logger is enabled at log.LevelTrace, a full net/http/httptrace lifecycle plus the raw response body. Authorization and other sensitive headers are always redacted. A nil logger is a no-op: no request logging is emitted and the transport is left untouched, so existing callers see byte-identical behavior.
WithLogger composes with WithHTTPClient and WithRoundTripper: the logging RoundTripper is installed by New AFTER all options have been applied, so it wraps whatever Transport ended up on the client. Order between WithLogger and WithRoundTripper / WithHTTPClient is irrelevant.
func WithMaxRetries ¶
WithMaxRetries sets the maximum number of 429 retry attempts.
func WithNetworkBackoff ¶
WithNetworkBackoff overrides the base and max backoff durations for transient network-error retries. Exposed primarily for tests.
func WithRateLimitBackoff ¶
WithRateLimitBackoff overrides the base and max backoff durations for 429 retries. Exposed primarily for tests that need sub-second backoffs.
func WithRoundTripper ¶
func WithRoundTripper(rt http.RoundTripper) Option
WithRoundTripper replaces only the transport on the default http.Client. Useful when a custom transport is needed without a full http.Client.
func WithUserAgent ¶ added in v0.4.2
WithUserAgent overrides the default User-Agent header value sent on every request. The default is buildinfo.UserAgent, so the stamped build identity is reported automatically; this option is provided for callers (typically downstream library consumers) that need to advertise their own product name in the header.
An empty string is ignored so callers cannot accidentally clobber the default with a zero value.
type SearchResult ¶
SearchResult is the result of a Search call. Keys lists the issue keys returned by the JQL query, in the order the Jira API returned them. NextPageToken is the opaque cursor for the next page; an empty value means there are no more pages. v0.1 does not paginate automatically; callers that need more than maxResults must call Search again with the returned token (post-MVP capability).
type Transition ¶
Transition is one workflow transition available for an issue, projected from Jira's GET .../transitions response: id + display name + the name of the status the issue moves to when the transition is executed.
type TransitionOption ¶
type TransitionOption func(*fieldsBuilder)
TransitionOption customizes a Client.TransitionIssue request body — either by merging additional fields/update ops onto the standard {"transition": {"id": "..."}} body, or by appending a comment via WithTransitionCommentText. It is layered on the same internal [fieldsBuilder] used by Create/Update so the marshalling logic does not diverge.
func WithTransitionCommentText ¶
func WithTransitionCommentText(text string) TransitionOption
WithTransitionCommentText appends a comment-add op with an ADF body (built via adf.BuildParagraphDoc) to the transition's update map. The resulting body is {"transition":{"id":...}, "update":{"comment":[{"add":{"body":<ADF>}}]}}.
func WithTransitionField ¶
func WithTransitionField(fieldID string, value any) TransitionOption
WithTransitionField sets fields[fieldID]=value during a transition. Useful for transitions that require a resolution, a comment, or any custom field. Mirrors WithField but for the transition body shape.
type UpdateOption ¶
type UpdateOption func(*fieldsBuilder)
UpdateOption customizes an UpdateIssue request body. Same shape as CreateOption but a distinct named type so the compiler keeps Create-only options (like WithParent) out of Update call sites.
func WithAssigneeAccountIDUpdate ¶
func WithAssigneeAccountIDUpdate(id string) UpdateOption
WithAssigneeAccountIDUpdate sets the assignee by accountId on an Update request.
func WithDescriptionADFUpdate ¶
func WithDescriptionADFUpdate(doc json.RawMessage) UpdateOption
WithDescriptionADFUpdate sets the issue description from a caller-supplied ADF document on an Update request.
func WithDescriptionTextUpdate ¶
func WithDescriptionTextUpdate(text string) UpdateOption
WithDescriptionTextUpdate sets the issue description from plain text on an Update request, converting to ADF via adf.BuildParagraphDoc.
func WithFieldUpdate ¶
func WithFieldUpdate(fieldID string, value any) UpdateOption
WithFieldUpdate is the generic escape hatch on Update: set fields[fieldID]=value with no typed wrapper.
func WithLabelsUpdate ¶
func WithLabelsUpdate(labels ...string) UpdateOption
WithLabelsUpdate sets the labels array on an Update request. Use WithUpdateVerb for incremental "add" / "remove" semantics.
func WithRawFieldsUpdate ¶
func WithRawFieldsUpdate(m map[string]any) UpdateOption
WithRawFieldsUpdate merges a caller-supplied map into the fields object on an Update request.
func WithSummaryUpdate ¶
func WithSummaryUpdate(s string) UpdateOption
WithSummaryUpdate sets the issue summary on an Update request.
func WithUpdateVerb ¶
func WithUpdateVerb(fieldID, verb string, value any) UpdateOption
WithUpdateVerb appends an update op (verb is "add", "remove", or "set") for fieldID. Multi-valued fields like "labels" support incremental edits — call WithUpdateVerb several times to compose an operation list, applied by Jira in order. Update-only because the update verbs only have a defined meaning on existing issues.