Documentation
¶
Overview ¶
Package circleci is a minimal client for the CircleCI API. marge uses it to look behind a failing "ci/circleci: <job>" commit status and tell a build that really failed apart from one CircleCI cancelled itself, and to rerun the latter so the same commit gets a real verdict.
Builds are read through the v1.1 API; reruns go through the v2 workflow rerun endpoint, which also releases the jobs the cancel left blocked.
Only the handful of fields marge needs are modelled. The v1.1 build JSON is public for public projects; private projects and every rerun endpoint need an API token, sent as the Circle-Token header (never as basic auth or a query parameter).
Index ¶
Constants ¶
const DefaultBaseURL = "https://circleci.com"
DefaultBaseURL is the CircleCI API host.
Variables ¶
This section is empty.
Functions ¶
func LoadToken ¶
func LoadToken() string
LoadToken returns the CircleCI API token from the CIRCLECI_CLI_TOKEN environment variable or, failing that, from the token line of the CircleCI CLI's own config file (~/.circleci/cli.yml). It returns "" when neither is set, in which case only public projects can be inspected and no build can be retried.
Types ¶
type APIError ¶
type APIError struct {
StatusCode int
// Message is the "message" field of the error body, when present.
Message string
// Authenticated is true when the request carried a token. Without one,
// a 401/403/404 on a build usually means a private project, which the
// error message points out.
Authenticated bool
}
APIError is a non-2xx answer from the CircleCI API.
type Action ¶
type Action struct {
Name string `json:"name"`
Status string `json:"status"`
Canceled bool `json:"canceled"`
Failed bool `json:"failed"`
}
Action is the outcome of one step on one container.
type Build ¶
type Build struct {
BuildNum int `json:"build_num"`
BuildURL string `json:"build_url"`
Branch string `json:"branch"`
Status string `json:"status"`
Outcome string `json:"outcome"`
Lifecycle string `json:"lifecycle"`
VCSRevision string `json:"vcs_revision"`
Canceled bool `json:"canceled"`
Steps []Step `json:"steps"`
Workflows Workflow `json:"workflows"`
}
Build is the subset of a v1.1 build that marge inspects.
func (*Build) AutoCancelled ¶
AutoCancelled reports whether the build ended because it was cancelled rather than because a step failed.
Verified against the live v1.1 API: when CircleCI auto-cancels a running build (a newer pipeline started on the same branch, or a redundant workflow was detected) it records the build with status and outcome "failed" and the top-level canceled flag false -- indistinguishable from a real failure at that level. The steps tell the two apart: an auto-cancelled build has every action "success" up to the point of cancellation and only "canceled" actions from there on, while a real failure has an action with status "failed". A build cancelled before any step ran carries status/outcome "canceled" instead.
The verdict is conservative: a build with a failed step that was cancelled afterwards, a timed-out step or an infrastructure failure is not an auto-cancel.
type BuildRef ¶
type BuildRef struct {
// VCS is the API path segment for the VCS provider: "github" or
// "bitbucket".
VCS string
Owner string
Repo string
Num int
}
BuildRef identifies one CircleCI job -- a "build" in v1.1 terms -- by the path components the API uses.
func ParseBuildURL ¶
ParseBuildURL extracts the build reference from the target_url CircleCI attaches to its commit statuses. Two shapes are recognised:
https://circleci.com/gh/<owner>/<repo>/<build_num> https://app.circleci.com/pipelines/github/<owner>/<repo>/<pipeline>/workflows/<id>/jobs/<build_num>
Anything else -- another CI system, a CircleCI URL without a build number -- returns ok == false.
type Client ¶
type Client struct {
HTTPClient *http.Client
BaseURL string
// Token is sent as the Circle-Token header on every request when set.
// Public projects can be read without one; private projects and the
// retry endpoint require it.
Token string
}
Client talks to the CircleCI v1.1 API. The zero value is not usable; use NewClient, or set BaseURL and HTTPClient explicitly (tests do).
func NewClient ¶
func NewClient() *Client
NewClient returns a client for circleci.com whose token, if any, comes from LoadToken.
func (*Client) RerunWorkflowFromFailed ¶ added in v0.10.1
RerunWorkflowFromFailed asks CircleCI to run the workflow again from its failed jobs. Unlike Retry it also releases the jobs that depend on the failed one, so a repository whose branch protection requires those downstream contexts gets them.
CircleCI reruns from a failed job, so it needs one: a workflow cancelled before any job failed has none and the endpoint answers 400. The id of the new workflow run is not read; the caller identifies the rerun by the workflow it asked for. The endpoint requires a token.
func (*Client) Retry ¶
Retry asks CircleCI to run the single build again on the same commit and returns the new build. The endpoint requires a token.
A build retried this way runs on its own: the jobs that the workflow had left blocked or not run because of the cancel stay where they are. Prefer RerunWorkflowFromFailed whenever the build carries a workflow id.
type Workflow ¶ added in v0.10.1
type Workflow struct {
JobName string `json:"job_name"`
// WorkflowID is the handle the v2 rerun endpoint takes.
WorkflowID string `json:"workflow_id"`
WorkflowName string `json:"workflow_name"`
}
Workflow is the workflow run a build belongs to. A build outside a workflow carries an empty one.