Skip to content

Commit 61ba5fb

Browse files
authored
Merge branch 'main' into rtinianov_fixStdTest
2 parents 12eddf6 + 8817bb8 commit 61ba5fb

31 files changed

+2998
-869
lines changed

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module github.com/smartcontractkit/chainlink-common
33
go 1.24.5
44

55
require (
6+
github.com/Masterminds/semver/v3 v3.4.0
67
github.com/XSAM/otelsql v0.37.0
78
github.com/andybalholm/brotli v1.1.1
89
github.com/atombender/go-jsonschema v0.16.1-0.20240916205339-a74cd4e2851c
@@ -38,7 +39,7 @@ require (
3839
github.com/smartcontractkit/chain-selectors v1.0.67
3940
github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.1
4041
github.com/smartcontractkit/chainlink-protos/billing/go v0.0.0-20250722225531-876fd6b94976
41-
github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20250905211734-167560f092c1
42+
github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20250911124514-5874cc6d62b2
4243
github.com/smartcontractkit/chainlink-protos/storage-service v0.3.0
4344
github.com/smartcontractkit/freeport v0.1.3-0.20250716200817-cb5dfd0e369e
4445
github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7
@@ -76,7 +77,6 @@ require (
7677
)
7778

7879
require (
79-
github.com/Masterminds/semver/v3 v3.4.0 // indirect
8080
github.com/apache/arrow-go/v18 v18.3.1 // indirect
8181
github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59 // indirect
8282
github.com/bahlo/generic-list-go v0.2.0 // indirect

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,8 +330,8 @@ github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.1 h1:ca2z5OXgn
330330
github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.1/go.mod h1:NZv/qKYGFRnkjOYBouajnDfFoZ+WDa6H2KNmSf1dnKc=
331331
github.com/smartcontractkit/chainlink-protos/billing/go v0.0.0-20250722225531-876fd6b94976 h1:mF3FiDUoV0QbJcks9R2y7ydqntNL1Z0VCPBJgx/Ms+0=
332332
github.com/smartcontractkit/chainlink-protos/billing/go v0.0.0-20250722225531-876fd6b94976/go.mod h1:HHGeDUpAsPa0pmOx7wrByCitjQ0mbUxf0R9v+g67uCA=
333-
github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20250905211734-167560f092c1 h1:HZt/80mhcNw6/MlYBIRracxfHWNqFF0iZ5nZEVZBUgo=
334-
github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20250905211734-167560f092c1/go.mod h1:jUC52kZzEnWF9tddHh85zolKybmLpbQ1oNA4FjOHt1Q=
333+
github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20250911124514-5874cc6d62b2 h1:1/KdO5AbUr3CmpLjMPuJXPo2wHMbfB8mldKLsg7D4M8=
334+
github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20250911124514-5874cc6d62b2/go.mod h1:jUC52kZzEnWF9tddHh85zolKybmLpbQ1oNA4FjOHt1Q=
335335
github.com/smartcontractkit/chainlink-protos/storage-service v0.3.0 h1:B7itmjy+CMJ26elVw/cAJqqhBQ3Xa/mBYWK0/rQ5MuI=
336336
github.com/smartcontractkit/chainlink-protos/storage-service v0.3.0/go.mod h1:h6kqaGajbNRrezm56zhx03p0mVmmA2xxj7E/M4ytLUA=
337337
github.com/smartcontractkit/chainlink-protos/workflows/go v0.0.0-20250822025801-598d3d86f873 h1:8/qwOmcdSFa8A6ecnj3eH/mwNx7Ybw2tjQFydDymtOc=

pkg/capabilities/registry/base.go

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ import (
44
"context"
55
"errors"
66
"fmt"
7+
"strings"
78
"sync"
89

10+
"github.com/Masterminds/semver/v3"
11+
912
"github.com/smartcontractkit/chainlink-common/pkg/capabilities"
1013
"github.com/smartcontractkit/chainlink-common/pkg/logger"
1114
"github.com/smartcontractkit/chainlink-common/pkg/types/core"
@@ -36,11 +39,58 @@ func (r *baseRegistry) Get(_ context.Context, id string) (capabilities.BaseCapab
3639
r.mu.RLock()
3740
defer r.mu.RUnlock()
3841
c, ok := r.m[id]
39-
if !ok {
40-
return nil, fmt.Errorf("capability not found with id %s", id)
42+
if ok {
43+
return c, nil
44+
}
45+
46+
// Find compatible version (>= requested version with same major)
47+
parts := strings.Split(id, "@")
48+
if len(parts) != 2 {
49+
return nil, fmt.Errorf("invalid capability id format: %s", id)
4150
}
51+
name, verStr := parts[0], parts[1]
4252

43-
return c, nil
53+
reqVer, err := semver.NewVersion(verStr)
54+
if err != nil {
55+
return nil, fmt.Errorf("invalid version in capability id %q: %w", id, err)
56+
}
57+
reqIsPrerelease := reqVer.Prerelease() != ""
58+
59+
var bestCap capabilities.BaseCapability
60+
var bestVer *semver.Version
61+
for key, cap := range r.m {
62+
p := strings.Split(key, "@")
63+
if len(p) != 2 {
64+
continue
65+
}
66+
if p[0] != name {
67+
continue
68+
}
69+
v, err := semver.NewVersion(p[1])
70+
if err != nil {
71+
continue
72+
}
73+
if v.Major() != reqVer.Major() {
74+
continue
75+
}
76+
// If the request is stable, skip pre-release candidates
77+
if !reqIsPrerelease && v.Prerelease() != "" {
78+
continue
79+
}
80+
81+
if v.GreaterThan(reqVer) {
82+
if bestVer == nil || v.LessThan(bestVer) {
83+
bestCap = cap
84+
bestVer = v
85+
}
86+
}
87+
}
88+
89+
if bestCap != nil {
90+
r.lggr.Debugw("found compatible capability", "id", name+"@"+bestVer.String())
91+
return bestCap, nil
92+
}
93+
return nil, fmt.Errorf("no compatible capability found for id %s", id)
4494
}
4595

4696
// GetTrigger gets a capability from the registry and tries to coerce it to the TriggerCapability interface.

pkg/capabilities/registry/base_test.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,95 @@ func TestRegistry(t *testing.T) {
5959
assert.Equal(t, c, cs[0])
6060
}
6161

62+
func TestRegistryCompatibleVersions(t *testing.T) {
63+
ctx := t.Context()
64+
65+
t.Run("Compatible minor version", func(t *testing.T) {
66+
r := registry.NewBaseRegistry(logger.Test(t))
67+
68+
ci, err := capabilities.NewCapabilityInfo(
69+
id,
70+
capabilities.CapabilityTypeAction,
71+
"capability-1-description",
72+
)
73+
require.NoError(t, err)
74+
75+
c := &mockCapability{CapabilityInfo: ci}
76+
err = r.Add(ctx, c)
77+
require.NoError(t, err)
78+
_, err = r.Get(ctx, "[email protected]")
79+
require.NoError(t, err)
80+
})
81+
82+
t.Run("Incompatible minor version", func(t *testing.T) {
83+
r := registry.NewBaseRegistry(logger.Test(t))
84+
85+
ci, err := capabilities.NewCapabilityInfo(
86+
id,
87+
capabilities.CapabilityTypeAction,
88+
"capability-1-description",
89+
)
90+
require.NoError(t, err)
91+
92+
c := &mockCapability{CapabilityInfo: ci}
93+
err = r.Add(ctx, c)
94+
require.NoError(t, err)
95+
_, err = r.Get(ctx, "[email protected]")
96+
require.Error(t, err)
97+
})
98+
99+
t.Run("Incompatible major version", func(t *testing.T) {
100+
r := registry.NewBaseRegistry(logger.Test(t))
101+
102+
ci, err := capabilities.NewCapabilityInfo(
103+
id,
104+
capabilities.CapabilityTypeAction,
105+
"capability-1-description",
106+
)
107+
require.NoError(t, err)
108+
109+
c := &mockCapability{CapabilityInfo: ci}
110+
err = r.Add(ctx, c)
111+
require.NoError(t, err)
112+
_, err = r.Get(ctx, "[email protected]")
113+
require.Error(t, err)
114+
})
115+
116+
t.Run("Don't match pre-release tags if requested version if not pre-release", func(t *testing.T) {
117+
r := registry.NewBaseRegistry(logger.Test(t))
118+
119+
ci, err := capabilities.NewCapabilityInfo(
120+
id,
121+
capabilities.CapabilityTypeAction,
122+
"capability-1-description",
123+
)
124+
require.NoError(t, err)
125+
126+
c := &mockCapability{CapabilityInfo: ci}
127+
err = r.Add(ctx, c)
128+
require.NoError(t, err)
129+
_, err = r.Get(ctx, "[email protected]")
130+
require.Error(t, err)
131+
})
132+
133+
t.Run("Match pre-release tags if requested version is pre-release", func(t *testing.T) {
134+
r := registry.NewBaseRegistry(logger.Test(t))
135+
136+
ci, err := capabilities.NewCapabilityInfo(
137+
id,
138+
capabilities.CapabilityTypeAction,
139+
"capability-1-description",
140+
)
141+
require.NoError(t, err)
142+
143+
c := &mockCapability{CapabilityInfo: ci}
144+
err = r.Add(ctx, c)
145+
require.NoError(t, err)
146+
_, err = r.Get(ctx, "[email protected]")
147+
require.NoError(t, err)
148+
})
149+
}
150+
62151
func TestRegistry_NoDuplicateIDs(t *testing.T) {
63152
r := registry.NewBaseRegistry(logger.Test(t))
64153
ctx := t.Context()

pkg/capabilities/v2/actions/http/client.pb.go

Lines changed: 36 additions & 34 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)