Skip to content
Open

V4 #3807

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
029e214
v3 -> v4 package paths and naming
DrJosh9000 Mar 31, 2026
b66ab96
Promote or delete experiments
DrJosh9000 Apr 8, 2026
e6df1d5
Remove deprecated docker integration
DrJosh9000 Apr 8, 2026
97cdd8d
Remove deprecated CLI flags
moskyb Apr 20, 2026
cf38299
Promote descending-spawn-priority experiment
moskyb Apr 14, 2026
3c1ba94
Merge pull request #3834 from buildkite/remove-deprecated-flags
DrJosh9000 Apr 20, 2026
9a78633
Print metadata from `meta-data get` with a newline after it
moskyb Apr 20, 2026
16c4990
Merge pull request #3835 from buildkite/newline-after-meta-data-get
DrJosh9000 Apr 20, 2026
d31729b
Remove deprecated plugin env vars
DrJosh9000 Apr 22, 2026
9d91146
fix: Reverse ordering for post- hooks
DrJosh9000 Apr 22, 2026
1839caf
Merge pull request #3852 from buildkite/remove-deprecated-plugin-env-…
DrJosh9000 Apr 22, 2026
bb966a4
Merge pull request #3853 from buildkite/a-1167-agent-hook-ordering-re…
DrJosh9000 Apr 23, 2026
67ff962
Replace `cancel-grace-period` and `signal-grace-period-seconds` with …
moskyb Apr 23, 2026
39f8587
Adjust defaults: cancel-signal-timeout 9 -> 10, cancel-cleanup-timeou…
moskyb Apr 30, 2026
c7559ca
Rip out opentracing tracing backend
moskyb Apr 29, 2026
4e1cf9a
Merge pull request #3868 from buildkite/graceless
moskyb Apr 30, 2026
469ceb5
Make pipeline secret redaction default behaviour
moskyb Mar 23, 2022
508a6ee
Merge pull request #3896 from buildkite/kill-opentracing-take-2
DrJosh9000 May 5, 2026
6aa4e61
Remove header times
DrJosh9000 May 7, 2026
3632da5
Bump changelog and VERSION for v4.0.0-beta.2
DrJosh9000 May 6, 2026
2bc9943
Merge pull request #3897 from buildkite/enforce-pipeline-reaction-mk-ii
DrJosh9000 May 6, 2026
18bc00a
ANSI timestamps only and always
DrJosh9000 May 7, 2026
c00fee4
Merge pull request #3898 from buildkite/release-v4.0.0-beta.2
DrJosh9000 May 6, 2026
afc4f1e
Upgrade to urfave/cli/v3
DrJosh9000 May 7, 2026
4363bda
Merge pull request #3899 from buildkite/remove-header-times
DrJosh9000 May 7, 2026
932615b
Bump version to v4.0.0-beta.3
DrJosh9000 May 19, 2026
df69547
Merge pull request #3904 from buildkite/urfave-cli-v3
DrJosh9000 May 7, 2026
b17c67e
Merge pull request #3929 from buildkite/v4.0.0-beta.3
DrJosh9000 May 19, 2026
be97647
A-1118: Replace addRepositoryHostToSSHKnownHosts with StrictHostKeyCh…
zhming0 Jan 21, 2026
929ee54
Merge pull request #3676 from buildkite/ming/pb-1068-refactor-1
zhming0 May 27, 2026
1a71d6d
chore: replace unlabelled jobStarted and jobEnded metrics with labelled
buildkate May 29, 2026
212c12a
Merge pull request #3966 from buildkite/kates/cleanup-prometheus-metrics
buildkate Jun 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .buildkite/steps/check-protobuf-generation.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ buf generate
if ! git diff --no-ext-diff --exit-code; then
echo ^^^ +++
echo "Generated protobuf files are out of sync with the source code"
echo "Please run \`buf generate\` in the internal/proto directory locally, and commit the result."
echo "Please run \`buf generate\` in the api/proto directory locally, and commit the result."
exit 1
fi
123 changes: 59 additions & 64 deletions EXPERIMENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ We frequently introduce new experimental features to the agent. You can use the
buildkite-agent start --experiment experiment1 --experiment experiment2
```

Or you can set them in your [agent configuration file](https://buildkite.com/docs/agent/v3/configuration):
Or you can set them in your [agent configuration file](https://buildkite.com/docs/agent/v4/configuration):

```
experiment="experiment1,experiment2"
Expand All @@ -18,25 +18,6 @@ If an experiment doesn't exist, no error will be raised.

## Available Experiments

### `normalised-upload-paths`

Artifacts found by `buildkite-agent artifact upload` will be uploaded using URI/Unix-style paths, even on Windows. This changes the URLs that artifacts uploaded from Windows agents are stored at, but to one which is URI-compatible.

Artifact names displayed in Buildkite's web UI, as well as in the API, are changed by this.

Take `buildkite-agent artifact upload coverage\report.xml` as an example:

- By default, and without this experiment, this file is uploaded to `s3://example/coverage\report.xml`.
- With this experiment enabled, it would be `s3://example/coverage/report.xml`.

**Status**: a major improvement for Windows compatibility, we'd like this to be the standard behaviour in 4.0. 👍👍

### `resolve-commit-after-checkout`

After repository checkout, resolve `BUILDKITE_COMMIT` to a commit hash. This makes `BUILDKITE_COMMIT` useful for builds triggered against non-commit-hash refs such as `HEAD`.

**Status**: broadly useful, we'd like this to be the standard behaviour in 4.0. 👍👍

### `agent-api`

This exposes a local API for interacting with the agent process.
Expand All @@ -58,17 +39,6 @@ the PTY to modify the stream. (Or do we? That's why this is an experiment)

**Status:** Experimental for some opt-in testing before being promoted to always-on.

### `override-zero-exit-on-cancel`

If the job is cancelled, and the exit status of the process is 0, it is overridden to be 1 instead.

When cancelling a job, the agent signals the process, which typically causes it to exit with a
non-zero status code. On Windows this is not true - the process exits with code 0 instead, which
makes the job appear to be successful. (It successfully exited, no?) By overriding the status to 1,
a cancelled job should appear as a failure, regardless of the OS the agent is running on.

**Status:** Experimental for some opt-in testing. We hope to promote this to be the default soon™.

### `interpolation-prefers-runtime-env`

When interpolating the pipeline level environment block, a pipeline level environment variable could take precedence over environment variables depending on the ordering. This may contravene Buildkite's [documentation](https://buildkite.com/docs/pipelines/environment-variables#environment-variable-precedence) that suggests the Job runtime environment takes precedence over that defined by combining environment variables defined in a pipeline.
Expand All @@ -77,41 +47,66 @@ We previously made this the default behaviour of the agent (as of v3.63.0) but h

**Status:** Available as an experiment to allow users who have since depended on this behaviour to re-enable it. If you use this feature please let us know so we may better understand your use case.

### `allow-artifact-path-traversal`

Uploaded artifacts include a relative path used by the artifact downloader to download the artifact to a suitable location relative to the destination path. In most circumstances the relative paths generated by `artifact upload` won't contain `..` components, and so will always be downloaded at or inside the destination path.

However, it is possible to upload artifacts using glob patterns containing one or more `..` components, which may be preserved in the artifact path. It is also possible for a user to call the Agent REST API directly in order to upload artifacts with arbitrary paths.

Leaving this experiment disabled prevents `..` components in artifact paths from traversing up from the destination path. Enabling this experiment permits the less-secure behaviour of allowing artifact paths containing `..` to traverse up the destination path.

For example, if an artifact was uploaded with the path `../../foo.txt`, then the command:

```shell
buildkite-agent artifact download '*.txt' .
```

has a different effect depending on this experiment:

- With `allow-artifact-path-traversal` disabled, `foo.txt` is downloaded to `./foo.txt`.
- With `allow-artifact-path-traversal` enabled, `foo.txt` is downloaded to `../../foo.txt`.

**Status:** This experiment is an escape hatch for a security fix. While the new behaviour is more secure, it may break downloading of legitimately-uploaded artifacts.

### `descending-spawn-priority`

When using `--spawn` with `--spawn-with-priority`, the agent assigns ascending priorities to each spawned agent (1, 2, 3, ...). This experiment changes the priorities to be descending (-1, -2, -3, ...) instead. This helps jobs be assigned across all hosts in cases where the value of `--spawn` varies between hosts.

**Status:** Experimental as an escape hatch to default behaviour. Will soon be promoted to a regular flag.

### `propagate-agent-config-vars`

Prepends agent configuration variables (such as `BUILDKITE_GIT_*`, `BUILDKITE_SHELL`, `BUILDKITE_CANCEL_GRACE_PERIOD`, etc.) to the environment file used by the job runner. This is useful in environments like Docker where the agent configuration is not otherwise available to the job process.

**Status:** Experimental while we test the impact on job environments

### `zip-plugins`

Allows plugins to be downloaded as zip archives instead of being cloned from a Git repository. This is useful for plugins hosted as zip files on HTTP(S) URLs.

**Status:** Experimental while we test zip archive support for plugins.

### `legacy-post-hook-order`

This experiment is an escape hatch that reverts to the v3 execution order of `post-checkout` and `post-command` hooks.

In Agent v3, hooks of any kind would run in the same order as one another (for plugins, the order in which plugins are specified for a step). In v4, multiple `post-checkout`, `post-command`, or `pre-exit` hooks execute in _reverse_ order. This change makes it easier for multiple plugins and hooks to compose.

For example, suppose a step specifies two plugins A and B, and there are also agent and repository hooks. Under version 3, each hook type would execute in the same order:

- agent pre-checkout
- (pre-checkout is not possible for repository hooks)
- plugin A pre-checkout
- plugin B pre-checkout
- (checkout)
- agent post-checkout
- repository post-checkout
- plugin A post-checkout
- plugin B post-checkout
- agent pre-command
- repository pre-command
- plugin A pre-command
- plugin B pre-command
- (command)
- agent post-command
- repository post-command
- plugin A post-command
- plugin B post-command
- agent pre-exit
- repository pre-exit
- plugin A pre-exit
- plugin B pre-exit

Under version 4, the execution order is (key differences in bold):

- agent pre-checkout
- (pre-checkout is not possible for repository hooks)
- plugin A pre-checkout
- plugin B pre-checkout
- (checkout)
- plugin **B** post-checkout
- plugin **A** post-checkout
- **repository** post-checkout
- **agent** post-checkout
- agent pre-command
- repository pre-command
- plugin A pre-command
- plugin B pre-command
- (command)
- plugin **B** post-command
- plugin **A** post-command
- **repository** post-command
- **agent** post-command
- plugin **B** pre-exit
- plugin **A** pre-exit
- **repository** pre-exit
- **agent** pre-exit

**Status:** This escape-hatch experiment will be removed in a future release, once we are confident that it isn't needed.
23 changes: 13 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Buildkite Agent

![Build status](https://badge.buildkite.com/08e4e12a0a1e478f0994eb1e8d51822c5c74d395.svg?branch=main)
[![Go Reference](https://pkg.go.dev/badge/github.com/buildkite/agent/v3.svg)](https://pkg.go.dev/github.com/buildkite/agent/v3)
[![Go Reference](https://pkg.go.dev/badge/github.com/buildkite/agent/v4.svg)](https://pkg.go.dev/github.com/buildkite/agent/v4)

The buildkite-agent is a small, reliable, and cross-platform build runner that
makes it easy to run automated builds on your own infrastructure. It’s main
Expand Down Expand Up @@ -46,7 +46,7 @@ platforms without extras. On Linux hosts it requires `dbus`.

[The agents page](https://buildkite.com/organizations/-/agents) on Buildkite has
personalised instructions, or you can refer to
[the Buildkite docs](https://buildkite.com/docs/agent/v3/installation). Both
[the Buildkite docs](https://buildkite.com/docs/agent/v4/installation). Both
cover installing the agent with Ubuntu (via apt), Debian (via apt), macOS (via
homebrew), Windows and Linux.

Expand Down Expand Up @@ -126,9 +126,11 @@ our Go dependencies. Dependencies are not
[vendored](https://go.dev/ref/mod#go-mod-vendor) into the repository unless
necessary.

The Go module published by this repo (i.e. the one you could use by adding `import "github.com/buildkite/agent/v3"` to your code)
is **not considered to be versioned using semantic versioning**. Breaking changes may be introduced in minor releases. Use
the agent as a runtime depedency of your Go app at your own risk.
The Go module published by this repo (i.e. the one you could use by adding
`import "github.com/buildkite/agent/v4"` to your code) is **not considered to be
versioned using semantic versioning**. Breaking changes may be introduced in
minor releases. Use the agent as a runtime depedency of your Go app at your own
risk.

## Platform Support

Expand Down Expand Up @@ -193,12 +195,13 @@ like systems, as well as Windows.
- Server 2022

[^1]: See https://github.com/golang/go/issues/23011 for macOS / Go support and
[Supported macOS Versions](./docs/macos.md) for the last supported version of the
Buildkite Agent for versions of macOS prior to those listed above.
[Supported macOS Versions](./docs/macos.md) for the last supported version of
the Buildkite Agent for versions of macOS prior to those listed above.

[^2]: See [Go's Windows support page](https://go.dev/wiki/Windows) for Go / Windows version
compatibility and [Supported Windows Versions](./docs/windows.md) for the last supported version
of the Buildkite Agent for versions of Windows prior to those listed above.
[^2]: See [Go's Windows support page](https://go.dev/wiki/Windows) for Go /
Windows version compatibility and [Supported Windows
Versions](./docs/windows.md) for the last supported version of the Buildkite
Agent for versions of Windows prior to those listed above.

## Contributing

Expand Down
7 changes: 2 additions & 5 deletions agent/agent_configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,12 @@ type AgentConfiguration struct {
VerificationJWKS any // The set of keys to verify jobs with
VerificationFailureBehaviour string // What to do if job verification fails (one of `block` or `warn`)

ANSITimestamps bool
TimestampLines bool
HealthCheckAddr string
DisconnectAfterJob bool
DisconnectAfterIdleTimeout time.Duration
DisconnectAfterUptime time.Duration
CancelGracePeriod int
SignalGracePeriod time.Duration
CancelSignalTimeout time.Duration
CancelCleanupTimeout time.Duration
EnableJobLogTmpfile bool
JobLogPath string
WriteJobLogsToStdout bool
Expand All @@ -73,7 +71,6 @@ type AgentConfiguration struct {
TracingBackend string
TracingServiceName string
TracingPropagateTraceparent bool
TraceContextEncoding string
DisableWarningsFor []string
AllowMultipartArtifactUpload bool

Expand Down
4 changes: 2 additions & 2 deletions agent/agent_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import (
"sync"
"time"

"github.com/buildkite/agent/v3/logger"
"github.com/buildkite/agent/v3/status"
"github.com/buildkite/agent/v4/logger"
"github.com/buildkite/agent/v4/status"

"github.com/prometheus/client_golang/prometheus/promhttp"
)
Expand Down
21 changes: 8 additions & 13 deletions agent/agent_worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ import (
"time"

"connectrpc.com/connect"
"github.com/buildkite/agent/v3/api"
"github.com/buildkite/agent/v3/core"
"github.com/buildkite/agent/v3/internal/process"
"github.com/buildkite/agent/v3/logger"
"github.com/buildkite/agent/v3/metrics"
"github.com/buildkite/agent/v3/status"
"github.com/buildkite/agent/v4/api"
"github.com/buildkite/agent/v4/core"
"github.com/buildkite/agent/v4/internal/process"
"github.com/buildkite/agent/v4/logger"
"github.com/buildkite/agent/v4/metrics"
"github.com/buildkite/agent/v4/status"
"github.com/buildkite/roko"
)

Expand Down Expand Up @@ -510,13 +510,8 @@ func (a *AgentWorker) RunJob(ctx context.Context, acceptResponse *api.Job, ignor
priorityLabel := strconv.Itoa(acceptResponse.Priority)
queueLabel := acceptResponse.Env["BUILDKITE_AGENT_META_DATA_QUEUE"]

// Legacy unlabelled counters; kept incrementing in lockstep with the
// labelled counters below so existing scrape consumers see no shape change.
jobsStarted.Inc()
defer jobsEnded.Inc()

jobsStartedWithLabels.WithLabelValues(priorityLabel, queueLabel).Inc()
defer jobsEndedWithLabels.WithLabelValues(priorityLabel, queueLabel).Inc()
jobsStarted.WithLabelValues(priorityLabel, queueLabel).Inc()
defer jobsEnded.WithLabelValues(priorityLabel, queueLabel).Inc()

running := jobsRunning.WithLabelValues(priorityLabel, queueLabel)
running.Inc()
Expand Down
6 changes: 3 additions & 3 deletions agent/agent_worker_action.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import (
"fmt"
"time"

"github.com/buildkite/agent/v3/api"
"github.com/buildkite/agent/v3/internal/ptr"
"github.com/buildkite/agent/v3/status"
"github.com/buildkite/agent/v4/api"
"github.com/buildkite/agent/v4/internal/ptr"
"github.com/buildkite/agent/v4/status"
"github.com/buildkite/roko"
)

Expand Down
2 changes: 1 addition & 1 deletion agent/agent_worker_heartbeat.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"context"
"time"

"github.com/buildkite/agent/v3/status"
"github.com/buildkite/agent/v4/status"
)

func (a *AgentWorker) runHeartbeatLoop(ctx context.Context) error {
Expand Down
4 changes: 2 additions & 2 deletions agent/agent_worker_ping.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (
"math/rand/v2"
"time"

"github.com/buildkite/agent/v3/api"
"github.com/buildkite/agent/v3/status"
"github.com/buildkite/agent/v4/api"
"github.com/buildkite/agent/v4/status"
)

// runPingLoop runs the (classical) loop that pings Buildkite for work.
Expand Down
4 changes: 2 additions & 2 deletions agent/agent_worker_streaming.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (
"time"

"connectrpc.com/connect"
agentedgev1 "github.com/buildkite/agent/v3/api/proto/gen"
"github.com/buildkite/agent/v3/status"
agentedgev1 "github.com/buildkite/agent/v4/api/proto/gen"
"github.com/buildkite/agent/v4/status"
)

// runStreamingPingLoop runs the streaming loop. It is best-effort
Expand Down
10 changes: 5 additions & 5 deletions agent/agent_worker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ import (
"time"

"connectrpc.com/connect"
"github.com/buildkite/agent/v3/api"
agentedgev1 "github.com/buildkite/agent/v3/api/proto/gen"
"github.com/buildkite/agent/v3/core"
"github.com/buildkite/agent/v3/logger"
"github.com/buildkite/agent/v3/metrics"
"github.com/buildkite/agent/v4/api"
agentedgev1 "github.com/buildkite/agent/v4/api/proto/gen"
"github.com/buildkite/agent/v4/core"
"github.com/buildkite/agent/v4/logger"
"github.com/buildkite/agent/v4/metrics"
"github.com/google/go-cmp/cmp"
"github.com/google/uuid"
)
Expand Down
2 changes: 1 addition & 1 deletion agent/ec2_tags.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"fmt"
"io"

"github.com/buildkite/agent/v3/internal/awslib"
"github.com/buildkite/agent/v4/internal/awslib"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
Expand Down
2 changes: 1 addition & 1 deletion agent/ecs_meta_data.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"strconv"

metadata "github.com/brunoscheufler/aws-ecs-metadata-go"
"github.com/buildkite/agent/v3/internal/agenthttp"
"github.com/buildkite/agent/v4/internal/agenthttp"
)

type ECSMetadata struct {
Expand Down
6 changes: 3 additions & 3 deletions agent/fake_api_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ import (
"time"

"connectrpc.com/connect"
"github.com/buildkite/agent/v3/api"
agentedgev1 "github.com/buildkite/agent/v3/api/proto/gen"
"github.com/buildkite/agent/v3/api/proto/gen/agentedgev1connect"
"github.com/buildkite/agent/v4/api"
agentedgev1 "github.com/buildkite/agent/v4/api/proto/gen"
"github.com/buildkite/agent/v4/api/proto/gen/agentedgev1connect"
"github.com/google/uuid"
)

Expand Down
Loading