A Go library and client for the Buildkite API. This project draws a lot of its structure and testing methods from go-github.
To get the package, execute:
go get github.com/buildkite/go-buildkite/v5
Simple shortened example for listing all pipelines:
import (
"github.com/buildkite/go-buildkite/v5"
"github.com/alecthomas/kingpin/v2"
)
var (
apiToken = kingpin.Flag("token", "API token").Required().String()
org = kingpin.Flag("org", "Organization slug").Required().String()
)
client, err := buildkite.NewOpts(buildkite.WithTokenAuth(*apiToken))
if err != nil {
log.Fatalf("client config failed: %s", err)
}
pipelines, _, err := client.Pipelines.List(*org, nil)Use client.TestWorkflows to list and inspect workflows within a suite.
Suite paths accept a slug or UUID. Requests require read_suites.
Response types include monitor conditions, filters, alarm/recovery action configuration, identity, and links. Pointer fields distinguish absent fields from zero thresholds or null labels. Webhook endpoints retain the API's redaction. Unknown response types remain readable, and unknown response fields are ignored.
workflow, _, err := client.TestWorkflows.Get(ctx, org, suite, workflowID)See the workflow example for listing and inspection. Unavailable or unauthorized requests return errors rather than an empty workflow list. Workflow writes and event history are not included.
Version 5 changes update request structs so PATCH requests can distinguish "leave this field unchanged" from "send this field with an empty value".
Update fields that can be cleared now use buildkite.Optional[T]. The zero
value omits the field. Wrap values with buildkite.Some(...) when the field
should be sent, including empty strings, empty maps, empty slices, 0, or
false.
Use initialized empty slices and maps when the API expects [] or {}. Nil
slices and maps wrapped with buildkite.Some(...) are encoded as null.
_, _, err := client.Pipelines.Update(ctx, org, pipelineSlug, buildkite.UpdatePipeline{
Description: buildkite.Some(""),
Tags: buildkite.Some([]string{}),
SkipQueuedBranchBuilds: buildkite.Some(false),
})_, _, err := client.PipelineSchedules.Update(ctx, org, pipelineSlug, scheduleID, buildkite.UpdatePipelineSchedule{
Env: buildkite.Some(map[string]string{}),
Enabled: buildkite.Some(false),
})Leaving an Optional[T] unset omits that field from the PATCH body:
_, _, err := client.Clusters.Update(ctx, org, clusterID, buildkite.ClusterUpdate{
Name: buildkite.Some("macOS builders"),
// Description is unchanged.
})Use buildkite.Null[T]() to send explicit JSON null for a nullable field.
For example, BranchConfiguration: buildkite.Null[string]() clears the stored
pipeline branch filter. buildkite.Some("") still sends an empty string, not null.
Only use Null where the API accepts null.
Some create/update request types were split so create calls keep plain required values while update calls use presence-aware fields:
ClusterTokenCreateUpdateis nowClusterTokenCreateandClusterTokenUpdate.PipelineTemplateCreateUpdateis nowPipelineTemplateCreateandPipelineTemplateUpdate.CreateTeamis still used for team creation;UpdateTeamis now used for team updates.TestSuitesService.Updatenow takesTestSuiteUpdate.
Use GitHubSettingsInput in CreatePipeline.ProviderSettings or
UpdatePipeline.ProviderSettings to send only the settings you specify.
Unset fields are omitted, Some(false) sends false, and Null[string]() clears
FilterCondition or PullRequestBranchFilterConfiguration.
_, _, err := client.Pipelines.Update(ctx, org, pipelineSlug, buildkite.UpdatePipeline{
BranchConfiguration: buildkite.Null[string](),
SkipQueuedBranchBuilds: buildkite.Some(false),
CancelRunningBranchBuilds: buildkite.Some(false),
ProviderSettings: buildkite.Some[buildkite.ProviderSettings](&buildkite.GitHubSettingsInput{
GitHubActionsMode: buildkite.Some(true),
GitHubWorkflowAccessTokensEnabled: buildkite.Some(true),
PublishCommitStatus: buildkite.Some(false),
TriggerMode: buildkite.Some("none"),
}),
})Pipeline responses still decode GitHub settings as *GitHubSettings. The new
GHAC and baseline boolean fields use pointers so absent fields stay absent and
explicit false values survive JSON readback. Existing fields and legacy
GitHubSettings writes keep their previous behavior, including sending every
existing boolean. Use GitHubSettingsInput for partial writes instead of
resending response settings. Existing response string fields still decode null
as an empty string; use the request type to choose omission, null, or a string.
On create, an omitted CreatePipeline.BranchConfiguration uses the API's null
default. On update, use Null[string]() to clear an existing branch filter.
These fields represent configuration, not server feature availability. They do not create a GitHub Actions pipeline trigger or repository webhook. Follow the native GHAC setup for the complete settings and separate trigger request. GitHub Enterprise Server is not supported by native GHAC setup or workflow access tokens.
Set CreatePipeline.PipelineTemplateUUID to create a pipeline backed by an
existing template. Leave Configuration and Steps unset; no placeholder YAML
is required. Without a template, supply YAML configuration or visual steps as
appropriate for the pipeline. The server validates template availability and
configuration requirements.
pipeline, _, err := client.Pipelines.Create(ctx, org, buildkite.CreatePipeline{
Name: "Example",
Repository: "https://github.com/example/repo.git",
ClusterID: clusterID,
PipelineTemplateUUID: templateUUID,
})On update, use PipelineTemplateUUID: buildkite.Some(templateUUID) to assign a
template, or PipelineTemplateUUID: buildkite.Null[string]() to remove the
assignment. Leaving the field unset preserves the existing assignment. If
needed, supply replacement Configuration in the same update. Pipeline
responses expose PipelineTemplateUUID as *string; null or absent values
decode as nil.
Use client.Pipelines.GetGitHubWebhookProcessing(ctx, org, pipelineSlug) to
read processing state. EnableGitHubWebhookProcessing and
DisableGitHubWebhookProcessing enable and disable it. All three return
(GitHubWebhookProcessing, *Response, error). The state includes URL,
Enabled, nullable DisabledAt (*Timestamp), and nullable DisabledBy
(*string, the user's name). Repeated enable or disable requests return the
current state.
These methods use GET, PUT, and DELETE on the pipeline's github-webhooks
endpoint, with no request body. They require Full Access to the pipeline and
read_pipelines for get or write_pipelines for enable/disable. Availability
depends on organization enrollment and a GitHub or GitHub Enterprise provider.
Permission/scope failures and availability/provider 404 responses remain API
errors; the client does not treat them as disabled state.
Disabling processing does not delete repository webhooks or disable dedicated
GitHub Actions pipeline triggers. AddWebhook remains the separate POST
webhook operation that creates a repository webhook.
See the examples directory for additional examples.
Note: not all API features are supported by go-buildkite just yet. If you need a feature, please make an issue or submit a pull request.
Use client.Jobs.GetJobConcurrencyByOrg(ctx, org, jobID) or
client.Jobs.GetJobConcurrency(ctx, org, pipeline, buildNumber, jobID) to read
JobConcurrency. Both require read_builds and a server with the job concurrency
endpoint available.
The response preserves nullable group, target limit, cluster ID, and state
timestamp fields. JobsAhead preserves the server's items, order, scope, and
notice. For a limited target, the server reads a bounded set of jobs ahead, then
leaves out jobs the caller's token cannot access. It returns the rest without
reading further to replace omitted jobs. The existing UI also reads a bounded
set and returns the list only if the viewer can access every selected job;
otherwise it returns 204 with no list.
JobsAhead.Scope is
subset_of_active_jobs_ahead_within_callers_scope_and_internal_limit.
JobsAhead.Notice preserves the server's warning:
Submission order is not execution order. This is not a complete list of jobs holding up this job because of concurrency limits; an empty list does not establish that there are no blockers.
This is not pagination, a full group, causal blockers, or future execution order.
Other target states retain their configuration but return empty items. An empty
list does not establish that there are no blockers. Copied from the job UI, only
the first returned item may have CurrentStateSince; even that timestamp may be
nil. General job REST endpoints already existed; this adds typed access to the
new concurrency-context REST endpoint.
- Generate a changelog using ghch:
ghch --format=markdown --next-version=v<next-version-number>, and update it inCHANGELOG.md - Commit the changelog
- Create a release using GitHub CLI:
gh release create, ensuring you update the release notes with the new CHANGELOG.md content
This library is distributed under the BSD-style license found in the LICENSE file.