Skip to content

Commit ed1a889

Browse files
Add per-changeset hook registration to fluent API (#796)
## Summary - Adds `WithPreHooks(...PreHook)` and `WithPostHooks(...PostHook)` to `ConfiguredChangeSet` and `PostProcessingChangeSet` interfaces - Hooks are stored on `ChangeSetImpl` and `PostProcessingChangeSetImpl`, propagated through `ThenWith`, and extracted into `registryEntry` via an internal `hookCarrier` interface when `Add()` is called - Multiple calls are additive (append, not replace) - Fully backward compatible — existing `Add()` call sites and tests are unchanged ## Test plan - [x] Package compiles cleanly - [x] 0 lint issues (`golangci-lint`) - [x] All existing changeset tests pass unchanged - Unit tests for hook registration and chaining coming in https://smartcontract-it.atlassian.net/browse/CLD-1270
1 parent a06e7ee commit ed1a889

File tree

4 files changed

+72
-3
lines changed

4 files changed

+72
-3
lines changed

.changeset/shaggy-bikes-decide.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"chainlink-deployments-framework": minor
3+
---
4+
5+
Add per-changeset hook registration via WithPreHooks/WithPostHooks fluent API

engine/cld/changeset/common.go

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"fmt"
77
"os"
88
"reflect"
9+
"slices"
910
"strings"
1011

1112
fresolvers "github.com/smartcontractkit/chainlink-deployments-framework/changeset/resolvers"
@@ -39,6 +40,8 @@ type ChangeSet internalChangeSet
3940
type ConfiguredChangeSet interface {
4041
ChangeSet
4142
ThenWith(postProcessor PostProcessor) PostProcessingChangeSet
43+
WithPreHooks(hooks ...PreHook) ConfiguredChangeSet
44+
WithPostHooks(hooks ...PostHook) ConfiguredChangeSet
4245
}
4346

4447
// WrappedChangeSet simply wraps a fdeployment.ChangeSetV2 to use it in the fluent interface, which hosts
@@ -264,6 +267,9 @@ type ChangeSetImpl[C any] struct {
264267
// Present only when the changeset was wired with
265268
// Configure(...).WithConfigResolver(...)
266269
ConfigResolver fresolvers.ConfigResolver
270+
271+
preHooks []PreHook
272+
postHooks []PostHook
267273
}
268274

269275
func (ccs ChangeSetImpl[C]) noop() {}
@@ -303,10 +309,28 @@ func (ccs ChangeSetImpl[C]) Configurations() (Configurations, error) {
303309
}, nil
304310
}
305311

306-
// ThenWith adds post-processing to a configured changeset
312+
// WithPreHooks appends pre-hooks to this changeset. Multiple calls are additive.
313+
func (ccs ChangeSetImpl[C]) WithPreHooks(hooks ...PreHook) ConfiguredChangeSet {
314+
ccs.preHooks = append(slices.Clone(ccs.preHooks), hooks...)
315+
return ccs
316+
}
317+
318+
// WithPostHooks appends post-hooks to this changeset. Multiple calls are additive.
319+
func (ccs ChangeSetImpl[C]) WithPostHooks(hooks ...PostHook) ConfiguredChangeSet {
320+
ccs.postHooks = append(slices.Clone(ccs.postHooks), hooks...)
321+
return ccs
322+
}
323+
324+
func (ccs ChangeSetImpl[C]) getPreHooks() []PreHook { return ccs.preHooks }
325+
func (ccs ChangeSetImpl[C]) getPostHooks() []PostHook { return ccs.postHooks }
326+
327+
// ThenWith adds post-processing to a configured changeset.
328+
// Hooks registered before ThenWith are carried forward.
307329
func (ccs ChangeSetImpl[C]) ThenWith(postProcessor PostProcessor) PostProcessingChangeSet {
308330
return PostProcessingChangeSetImpl[C]{
309331
changeset: ccs,
310332
postProcessor: postProcessor,
333+
preHooks: slices.Clone(ccs.preHooks),
334+
postHooks: slices.Clone(ccs.postHooks),
311335
}
312336
}

engine/cld/changeset/postprocess.go

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,26 @@
11
package changeset
22

33
import (
4+
"slices"
5+
46
fdeployment "github.com/smartcontractkit/chainlink-deployments-framework/deployment"
57
)
68

79
type PostProcessor func(e fdeployment.Environment, config fdeployment.ChangesetOutput) (fdeployment.ChangesetOutput, error)
810

9-
type PostProcessingChangeSet internalChangeSet
11+
type PostProcessingChangeSet interface {
12+
internalChangeSet
13+
WithPreHooks(hooks ...PreHook) PostProcessingChangeSet
14+
WithPostHooks(hooks ...PostHook) PostProcessingChangeSet
15+
}
1016

1117
var _ PostProcessingChangeSet = PostProcessingChangeSetImpl[any]{}
1218

1319
type PostProcessingChangeSetImpl[C any] struct {
1420
changeset ChangeSetImpl[C]
1521
postProcessor PostProcessor
22+
preHooks []PreHook
23+
postHooks []PostHook
1624
}
1725

1826
func (ccs PostProcessingChangeSetImpl[C]) noop() {}
@@ -30,3 +38,18 @@ func (ccs PostProcessingChangeSetImpl[C]) Apply(env fdeployment.Environment) (fd
3038
func (ccs PostProcessingChangeSetImpl[C]) Configurations() (Configurations, error) {
3139
return ccs.changeset.Configurations()
3240
}
41+
42+
// WithPreHooks appends pre-hooks to this changeset. Multiple calls are additive.
43+
func (ccs PostProcessingChangeSetImpl[C]) WithPreHooks(hooks ...PreHook) PostProcessingChangeSet {
44+
ccs.preHooks = append(slices.Clone(ccs.preHooks), hooks...)
45+
return ccs
46+
}
47+
48+
// WithPostHooks appends post-hooks to this changeset. Multiple calls are additive.
49+
func (ccs PostProcessingChangeSetImpl[C]) WithPostHooks(hooks ...PostHook) PostProcessingChangeSet {
50+
ccs.postHooks = append(slices.Clone(ccs.postHooks), hooks...)
51+
return ccs
52+
}
53+
54+
func (ccs PostProcessingChangeSetImpl[C]) getPreHooks() []PreHook { return ccs.preHooks }
55+
func (ccs PostProcessingChangeSetImpl[C]) getPostHooks() []PostHook { return ccs.postHooks }

engine/cld/changeset/registry.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,28 @@ type registryEntry struct {
7272

7373
// options contains the configuration options for this changeset
7474
options ChangesetConfig
75+
76+
preHooks []PreHook
77+
postHooks []PostHook
78+
}
79+
80+
// hookCarrier is implemented by changeset types that carry hooks through the
81+
// fluent API chain. Add() uses this to extract hooks into the registry entry.
82+
type hookCarrier interface {
83+
getPreHooks() []PreHook
84+
getPostHooks() []PostHook
7585
}
7686

7787
// newRegistryEntry creates a new registry entry for a changeset.
7888
func newRegistryEntry(c ChangeSet, opts ChangesetConfig) registryEntry {
79-
return registryEntry{changeset: c, options: opts}
89+
entry := registryEntry{changeset: c, options: opts}
90+
91+
if hc, ok := c.(hookCarrier); ok {
92+
entry.preHooks = hc.getPreHooks()
93+
entry.postHooks = hc.getPostHooks()
94+
}
95+
96+
return entry
8097
}
8198

8299
// newArchivedRegistryEntry creates a new registry entry for an archived changeset.

0 commit comments

Comments
 (0)