Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
115 commits
Select commit Hold shift + click to select a range
216cd18
Add type Capability and change interface
6543 Apr 26, 2026
89a6666
fix and load
6543 Apr 26, 2026
535fce1
Hetzner query Capabilities
6543 Apr 14, 2026
d60af19
Merge branch 'main' into update-architecutre
6543 Apr 26, 2026
3070e1d
hetzner use capability fully
6543 Apr 26, 2026
d95dec5
Apply suggestions from code review
6543 Apr 28, 2026
0f7cf12
unexport
6543 Apr 28, 2026
aa1f312
vultr: nits
6543 Apr 28, 2026
ff435f2
vultr: refactor and impruve
6543 Apr 29, 2026
be6846a
vultr: more debug info for image config
6543 Apr 29, 2026
2688ca3
move cloudinit template into global flag
6543 Apr 29, 2026
7a6637b
refactor(engine): extract queue demand and label helpers
6543 Apr 29, 2026
e0e76a6
feat(engine): bucket-aware capability- and label-driven scheduling
6543 Apr 29, 2026
a7afa80
engine: refactor and cleanup
6543 Apr 29, 2026
9559909
gitignore
6543 Apr 29, 2026
4ce4969
fix lint
6543 Apr 29, 2026
dbb9705
fix tests
6543 Apr 29, 2026
759f779
Merge branch 'main' into update-architecutre
6543 Apr 29, 2026
7d97128
hetzner update default flag values
6543 Apr 29, 2026
aea026c
fix tests (2)
6543 Apr 29, 2026
268d703
remove legacy "filter-labels" flag and refactor based on it
6543 Apr 29, 2026
13cc4cf
split predict.go into buckets.go and plan.go
6543 Apr 29, 2026
113c8b3
extract agentMatchesCapability predicate
6543 Apr 29, 2026
f8b1933
loadAgents: prefix match instead of regex
6543 Apr 29, 2026
6ff2623
plan: use min/max builtins, drop abs helper
6543 Apr 29, 2026
7fb0496
Reconcile: collapse dispatch loop, drop redundant per-decision logs
6543 Apr 29, 2026
ee9ef87
cleanupDanglingAgents: build set first, then iterate twice
6543 Apr 29, 2026
30fcd0e
labels: rename agentLabelsFor parameter cb -> capability
6543 Apr 29, 2026
3ad3b54
prepare vultr for other archs ... not relefat jet
6543 Apr 29, 2026
cf6933f
scaleway: support multible zones
6543 Apr 29, 2026
a25db24
scaleway: todo got resolved
6543 Apr 29, 2026
553ecc7
scaleway: use lib to validate requred parameter
6543 Apr 29, 2026
4247cbd
scaleway: more official alias usage
6543 Apr 29, 2026
03001a8
providers/linode: resolve Region+LinodeType in New(), real Capabiliti…
6543 Apr 29, 2026
ab002e0
providers/aws: resolve InstanceTypeInfo in New(), real Capabilities()
6543 Apr 29, 2026
3032ddf
providers/scaleway: resolve ServerType per zone in New(), real Capabi…
6543 Apr 29, 2026
4883334
providers/scaleway: multi-type multi-image hetzner-style model
6543 Apr 30, 2026
765e017
rm lint issue
6543 Apr 30, 2026
501feab
Update hetzner config
6543 Apr 30, 2026
6873e5f
remove deprications
6543 Apr 30, 2026
640f0e6
Hetzner: resolve server configs on startup
6543 Apr 30, 2026
d2208d6
update
6543 Apr 30, 2026
2da4c13
update
6543 Apr 30, 2026
57b21fb
cleanup
6543 Apr 30, 2026
f0f8801
cleanup
6543 Apr 30, 2026
b8b6465
cleanup test and start fixing
6543 Apr 30, 2026
c2fad20
fix err
6543 Apr 30, 2026
14035a7
cleanup test and start fixing
6543 Apr 30, 2026
ff984d8
more tests
6543 Apr 30, 2026
4a8b0c1
Merge branch 'main' into hetzner_enhance
6543 May 4, 2026
3fdee1d
Merge branch 'main' into hetzner_enhance
6543 May 19, 2026
38853bc
merge files
6543 May 19, 2026
7b429f8
Merge remote-tracking branch 'own/hetzner_enhance' into update-archit…
6543 May 19, 2026
16d2c66
fix merge conflict relicts
6543 May 19, 2026
2ff79a9
cleanup
6543 May 19, 2026
f63d5a5
clean
6543 May 19, 2026
90d2578
Merge branch 'main' into update-architecutre
6543 May 20, 2026
823e885
Merge branch 'main' into update-architecutre
6543 May 21, 2026
5de461a
cleanup bcause of v2.0
6543 May 21, 2026
15e90b1
Merge branch 'main' into update-architecutre
6543 May 26, 2026
020b3b2
Merge branch 'main' into update-architecutre
6543 Jun 2, 2026
206f572
Apply suggestion from @6543
6543 Jun 2, 2026
b20165b
clean
6543 Jun 2, 2026
50ab79a
readd comments
6543 Jun 2, 2026
ff38c21
Merge branch 'main' into update-architecutre
6543 Jun 6, 2026
084fc78
Merge branch 'main' into update-architecutre
6543 Jul 7, 2026
b8e350e
mockery
6543 Jul 7, 2026
8b902be
Port provider Capability implementations onto rebased head
6543 Jul 7, 2026
cac9407
fix(scaleway): return the backend validation error
6543 Jul 7, 2026
e9e9ad1
fix(engine): repair drainAgents after botched main merge
6543 Jul 7, 2026
4a72c76
fix(equinixmetal): implement the Capability provider interface
6543 Jul 7, 2026
e157ec0
refactor(providers): rename Capability parameter cb to capability
6543 Jul 7, 2026
8ec3917
fix(hetznercloud): return the backend validation error
6543 Jul 7, 2026
30b7ac4
fix(engine): adapt merged hourly-round-up tests to bucket model
6543 Jul 7, 2026
2c02c0f
fix(hetznercloud): correct mocks in first FallbackOnUnavailable test
6543 Jul 7, 2026
a51b107
Merge branch 'main' into update-architecutre
6543 Jul 7, 2026
9b00ab5
Update README.md
6543 Jul 7, 2026
32e3fb4
Merge branch 'main' into update-architecutre
6543 Jul 10, 2026
a8dff13
Merge branch 'main' into update-architecutre
6543 Jul 11, 2026
bd8eb21
test(engine): port busy-pool backlog regression test to rawDelta
claude Jul 11, 2026
66164ca
Merge branch 'main' into update-architecutre
6543 Jul 14, 2026
25941d9
reset aws to main
6543 Jul 20, 2026
f1f1b87
fix(aws): port capability discovery and selection onto rewritten prov…
claude Jul 20, 2026
4fd6343
feat(openstack): add capability discovery
codex Jul 20, 2026
ba4d876
simplfy interface
6543 Jul 20, 2026
07e91c2
simplify
6543 Jul 20, 2026
138ffcf
make build again
6543 Jul 20, 2026
81e89db
test(e2e): exercise autoscaler lifecycle
codex Jul 20, 2026
15f1d1a
refactor(engine): split autoscaler.go into topic files
claude Jul 20, 2026
6fd2258
fix(engine): mirror server label matching
claude Jul 20, 2026
987870c
fix(engine): attribute running tasks by agent
claude Jul 20, 2026
00b06a5
fix(engine): keep the fleet budget correct across buckets
claude Jul 20, 2026
a1eb43d
fix(engine): drain agents with unavailable capabilities
claude Jul 20, 2026
67d2130
test(e2e): tighten the lifecycle harness and cover more scenarios
claude Jul 20, 2026
45f6975
adjust test to pasthrough
6543 Jul 20, 2026
40f66f6
test(e2e): pack workflows per agent
claude Jul 20, 2026
18222c3
test(e2e): ignore unschedulable pending
claude Jul 20, 2026
c1ae93f
test(e2e): reap agents that never connect
claude Jul 20, 2026
59d267c
test(e2e): keep paid agents warm on hourly billing
claude Jul 20, 2026
df7218a
fix(engine): allow reactivation at pool limit
codex Jul 20, 2026
bf6f6b3
test(e2e): keep a draining agent that still runs work
claude Jul 20, 2026
f2789fb
test(e2e): reconcile provider/server drift
claude Jul 20, 2026
18263bf
test(e2e): hold steady without provider capabilities
claude Jul 20, 2026
e80532c
test(make): add test-e2e coverage target
claude Jul 20, 2026
1181345
ci: run e2e tests with coverage summary
claude Jul 20, 2026
93d1eac
fix(engine): attribute booting agents to their deploy bucket
claude Jul 20, 2026
37f4e0c
test(e2e): do not over-provision while agents boot
claude Jul 20, 2026
742a76e
feat(engine): bound agent startup with a creation timeout
claude Jul 20, 2026
688ecd5
fix(providers): report filtered fallback exhaustion
codex Jul 20, 2026
833e37d
fix(vultr): advertise x64 images as amd64
codex Jul 20, 2026
ad25a1b
fix(aws): skip unknown deploy architectures
codex Jul 20, 2026
7e5e4fa
fix(config): preserve startup timeout env alias
codex Jul 20, 2026
c3a28ff
fix(engine): replace agents with stale labels
codex Jul 20, 2026
3a897b6
Merge branch 'main' into update-architecutre
6543 Jul 24, 2026
10da1dd
Merge branch 'main' into update-architecutre
6543 Jul 28, 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
7 changes: 7 additions & 0 deletions .woodpecker/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,10 @@ steps:
commands:
- make test
when: *when

- name: test-e2e
image: *golang_image
depends_on: [vendor]
commands:
- make test-e2e
when: *when
7 changes: 7 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,13 @@ lint: install-tools ## Lint code
test-autoscaler: ## Test autoscaler code
go test -race -cover -coverprofile autoscaler-coverage.out -timeout 30s ${GO_PACKAGES}

.PHONY: test-e2e
test-e2e: ## Run end-to-end tests and report the engine coverage they exercise
go test -race -coverpkg=go.woodpecker-ci.org/autoscaler/engine/... -coverprofile e2e-coverage.out -timeout 60s go.woodpecker-ci.org/autoscaler/e2e
@echo
@echo "e2e coverage of engine:"
@go tool cover -func=e2e-coverage.out

.PHONY: test
test: test-autoscaler ## Run all tests

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,4 @@ The billing model is selected automatically by the provider, so no extra configu
- [ ] Remove agents which have not connected for a long time
- [x] Release as container image
- [x] Add docs
- [ ] Support agent deployment with specific attributes (e.g. platforms, architectures, etc.)
- [x] Support agent deployment with specific attributes (e.g. platforms, architectures, etc.)
6 changes: 6 additions & 0 deletions cmd/woodpecker-autoscaler/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ var flags = []cli.Flag{
Usage: "time an agent is allowed to be inactive before it can be terminated as duration string like 2h45m (https://pkg.go.dev/time#ParseDuration)",
Sources: cli.EnvVars("WOODPECKER_AGENT_INACTIVITY_TIMEOUT", "WOODPECKER_AGENT_ALLOWED_STARTUP_TIME"),
},
&cli.StringFlag{
Name: "agent-creation-timeout",
Value: "10m",
Usage: "time a deployed agent is allowed to take for its first contact with the server before it is replaced and torn down, as duration string like 2h45m (https://pkg.go.dev/time#ParseDuration)",
Sources: cli.EnvVars("WOODPECKER_AGENT_CREATION_TIMEOUT", "WOODPECKER_AGENT_ALLOWED_STARTUP_TIME"),
},
&cli.StringFlag{
Name: "agent-idle-timeout",
Value: "10m",
Expand Down
12 changes: 10 additions & 2 deletions cmd/woodpecker-autoscaler/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,18 +99,26 @@ func run(ctx context.Context, cmd *cli.Command) error {
}
config.BillingModel = provider.BillingModel()

autoscaler := engine.NewAutoscaler(provider, client, config)

config.AgentInactivityTimeout, err = time.ParseDuration(cmd.String("agent-inactivity-timeout"))
if err != nil {
return fmt.Errorf("can't parse agent-inactivity-timeout: %w", err)
}

config.AgentCreationTimeout, err = time.ParseDuration(cmd.String("agent-creation-timeout"))
if err != nil {
return fmt.Errorf("can't parse agent-creation-timeout: %w", err)
}

config.AgentIdleTimeout, err = time.ParseDuration(cmd.String("agent-idle-timeout"))
if err != nil {
return fmt.Errorf("can't parse agent-idle-timeout: %w", err)
}

autoscaler, err := engine.NewAutoscaler(ctx, provider, client, config)
if err != nil {
return fmt.Errorf("could not create autoscaler: %w", err)
}

config.AgentBillingTeardownMargin, err = time.ParseDuration(cmd.String("agent-billing-teardown-margin"))
if err != nil {
return fmt.Errorf("can't parse agent-billing-teardown-margin: %w", err)
Expand Down
10 changes: 8 additions & 2 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,14 @@ type Config struct {
GRPCSecure bool
AgentInactivityTimeout time.Duration
AgentIdleTimeout time.Duration
UserData string // cloudinit template
ExtraAgentLabels map[string]string
// AgentCreationTimeout is how long a deployed agent may take to make its
// first contact with the server. Past this deadline it no longer counts
// as bucket capacity and is reaped, so a stuck boot cannot stall the
// queue indefinitely. Zero disables the deadline; never-connected agents
// then fall back to AgentInactivityTimeout for reaping.
AgentCreationTimeout time.Duration
UserData string // cloudinit template
ExtraAgentLabels map[string]string

// BillingModel is taken from the selected provider and selects the teardown
// policy the engine applies to idle agents.
Expand Down
Loading