Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .github/workflows/pull-request-main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ on:
branches:
- main
- "releases/**"
- capabilities-development

env:
# Ensure that a cached go version is used:
Expand Down
21 changes: 21 additions & 0 deletions .github/workflows/validate-protos-version.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Validate chainlink-protos version

on:
push:
branches:
- capabilities-development
pull_request:
branches:
- capabilities-development

jobs:
validate-protos-version:
permissions:
contents: read
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6

- name: Validate protos version
uses: smartcontractkit/.github/actions/validate-protos-version@e5a68c3ae58d138e4e7d1d2bbc7918e2b51d7161 #v1.0.0
97 changes: 97 additions & 0 deletions .github/workflows/validate-sdk-version.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
name: Validate cre-sdk-go version

on:
push:
branches:
- capabilities-development
pull_request:
branches:
- capabilities-development

jobs:
validate-sdk-version:
permissions:
contents: read
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6

- name: Checkout cre-sdk-go
uses: actions/checkout@v6
with:
repository: smartcontractkit/cre-sdk-go
ref: capabilities-development
path: .cre-sdk-go
fetch-depth: 0
persist-credentials: false

- name: Validate cre-sdk-go versions are from capabilities-development
run: |
failed=0
found=0

# Find all lines in the root go.mod that depend on any cre-sdk-go module.
while IFS= read -r line; do
mod=$(echo "$line" | awk '{print $1}')
echo " parsed module: $mod"
version=$(echo "$line" | awk '{print $2}')
echo " parsed version: $version"

found=1

# Pseudo-versions have 3 parts separated by "-" and end with a 12-char hex commit hash.
# e.g. "v0.0.0-20260420204255-a3f3bdd56877" -> "a3f3bdd56877"
# Tagged versions like "v1.9.0-capdev.1" don't match this pattern.
suffix=${version##*-}
if [[ "$suffix" =~ ^[0-9a-f]{12}$ ]]; then
# Pseudo-version: use the commit hash directly.
commit="$suffix"
echo " parsed commit (pseudo-version): $commit"
else
# Tagged version: resolve the tag to a commit.
# The module path prefix (github.com/smartcontractkit/cre-sdk-go) maps to the
# repo root; any sub-module suffix becomes a tag prefix.
# e.g. module "github.com/smartcontractkit/cre-sdk-go/capabilities/blockchain/evm"
# with version "v1.0.0-beta.10-capdev.1" -> tag "capabilities/blockchain/evm/v1.0.0-beta.10-capdev.1"
subpath=${mod#github.com/smartcontractkit/cre-sdk-go}
subpath=${subpath#/}
if [[ -n "$subpath" ]]; then
tag="${subpath}/${version}"
else
tag="${version}"
fi
echo " resolved tag: $tag"
commit=$(git -C .cre-sdk-go rev-list -n1 "$tag" 2>/dev/null || true)
if [[ -z "$commit" ]]; then
echo "::error::$mod tag $tag not found in cre-sdk-go"
failed=1
continue
fi
echo " resolved commit: $commit"
fi

echo "Checking module=$mod version=$version commit=$commit"

# Verify the commit is reachable from capabilities-development.
if ! git -C .cre-sdk-go merge-base --is-ancestor "$commit" capabilities-development 2>/dev/null; then
echo "::error::$mod commit $commit is NOT on the capabilities-development branch of cre-sdk-go"
failed=1
else
echo "OK: $mod commit $commit is on capabilities-development"
fi
done < <(grep 'github.com/smartcontractkit/cre-sdk-go' go.mod | grep -v '^//')

if [[ "$found" -eq 0 ]]; then
echo "::error::No cre-sdk-go dependencies found in go.mod"
exit 1
fi

if [[ "$failed" -eq 1 ]]; then
echo ""
echo "One or more cre-sdk-go dependencies reference a commit not on capabilities-development."
exit 1
fi

echo ""
echo "All cre-sdk-go versions are from capabilities-development."
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
golang 1.25.5
golang 1.26.2
golangci-lint 2.11.2
goreleaser 2.0.1
python 3.10.5
Expand Down
34 changes: 20 additions & 14 deletions cmd/account/link_key/link_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,13 @@ type initiateLinkingResponse struct {
FunctionArgs []string `json:"functionArgs"`
}

func Exec(ctx *runtime.Context, in Inputs) error {
func Exec(parentCtx context.Context, ctx *runtime.Context, in Inputs) error {
h := newHandler(ctx, nil)

if err := h.ValidateInputs(in); err != nil {
return err
}
return h.Execute(in)
return h.Execute(parentCtx, in)
}

func New(runtimeContext *runtime.Context) *cobra.Command {
Expand All @@ -83,7 +83,7 @@ func New(runtimeContext *runtime.Context) *cobra.Command {
return err
}

return h.Execute(inputs)
return h.Execute(cmd.Context(), inputs)
},
}
settings.AddTxnTypeFlags(cmd)
Expand All @@ -101,6 +101,7 @@ type handler struct {
stdin io.Reader
environmentSet *environments.EnvironmentSet
wrc *client.WorkflowRegistryV2Client
execCtx context.Context

validated bool

Expand All @@ -109,28 +110,28 @@ type handler struct {
}

func newHandler(ctx *runtime.Context, stdin io.Reader) *handler {
h := handler{
return &handler{
settings: ctx.Settings,
credentials: ctx.Credentials,
clientFactory: ctx.ClientFactory,
log: ctx.Logger,
environmentSet: ctx.EnvironmentSet,
stdin: stdin,
wg: sync.WaitGroup{},
wrcErr: nil,
}
}

func (h *handler) initWorkflowRegistryClient() error {
h.wg.Add(1)
go func() {
defer h.wg.Done()
wrc, err := h.clientFactory.NewWorkflowRegistryV2Client()
wrc, err := h.clientFactory.NewWorkflowRegistryV2Client(h.execCtx)
if err != nil {
h.wrcErr = fmt.Errorf("failed to create workflow registry client: %w", err)
return
}
h.wrc = wrc
}()

return &h
return nil
}

func (h *handler) ResolveInputs(v *viper.Viper) (Inputs, error) {
Expand All @@ -154,11 +155,16 @@ func (h *handler) ValidateInputs(in Inputs) error {
return nil
}

func (h *handler) Execute(in Inputs) error {
func (h *handler) Execute(ctx context.Context, in Inputs) error {
if !h.validated {
return fmt.Errorf("inputs not validated")
}

h.execCtx = ctx
if err := h.initWorkflowRegistryClient(); err != nil {
return err
}

h.displayDetails()

if in.WorkflowOwnerLabel == "" {
Expand Down Expand Up @@ -191,7 +197,7 @@ func (h *handler) Execute(in Inputs) error {

ui.Dim(fmt.Sprintf("Starting linking: owner=%s, label=%s", in.WorkflowOwner, in.WorkflowOwnerLabel))

resp, err := h.callInitiateLinking(context.Background(), in)
resp, err := h.callInitiateLinking(h.execCtx, in)
if err != nil {
return err
}
Expand Down Expand Up @@ -296,10 +302,10 @@ func (h *handler) linkOwner(resp initiateLinkingResponse) error {
}

ownerAddr := common.HexToAddress(h.settings.Workflow.UserWorkflowSettings.WorkflowOwnerAddress)
if err := h.wrc.CanLinkOwner(ownerAddr, ts, proofBytes, sigBytes); err != nil {
if err := h.wrc.CanLinkOwner(h.execCtx, ownerAddr, ts, proofBytes, sigBytes); err != nil {
return fmt.Errorf("link request verification failed: %w", err)
}
txOut, err := h.wrc.LinkOwner(ts, proofBytes, sigBytes)
txOut, err := h.wrc.LinkOwner(h.execCtx, ts, proofBytes, sigBytes)
if err != nil {
return fmt.Errorf("LinkOwner failed: %w", err)
}
Expand Down Expand Up @@ -388,7 +394,7 @@ func (h *handler) checkIfAlreadyLinked() (bool, error) {
ownerAddr := common.HexToAddress(h.settings.Workflow.UserWorkflowSettings.WorkflowOwnerAddress)
ui.Dim("Checking existing registrations...")

linked, err := h.wrc.IsOwnerLinked(ownerAddr)
linked, err := h.wrc.IsOwnerLinked(h.execCtx, ownerAddr)
if err != nil {
return false, fmt.Errorf("failed to check owner link status: %w", err)
}
Expand Down
30 changes: 18 additions & 12 deletions cmd/account/unlink_key/unlink_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ type handler struct {
stdin io.Reader
environmentSet *environments.EnvironmentSet
wrc *client.WorkflowRegistryV2Client
execCtx context.Context

validated bool

Expand All @@ -83,7 +84,7 @@ func New(runtimeContext *runtime.Context) *cobra.Command {
if err := h.ValidateInputs(in); err != nil {
return err
}
return h.Execute(in)
return h.Execute(cmd.Context(), in)
},
}
settings.AddTxnTypeFlags(cmd)
Expand All @@ -92,28 +93,28 @@ func New(runtimeContext *runtime.Context) *cobra.Command {
}

func newHandler(ctx *runtime.Context, stdin io.Reader) *handler {
h := handler{
return &handler{
settings: ctx.Settings,
credentials: ctx.Credentials,
clientFactory: ctx.ClientFactory,
log: ctx.Logger,
environmentSet: ctx.EnvironmentSet,
stdin: stdin,
wg: sync.WaitGroup{},
wrcErr: nil,
}
}

func (h *handler) initWorkflowRegistryClient() error {
h.wg.Add(1)
go func() {
defer h.wg.Done()
wrc, err := h.clientFactory.NewWorkflowRegistryV2Client()
wrc, err := h.clientFactory.NewWorkflowRegistryV2Client(h.execCtx)
if err != nil {
h.wrcErr = fmt.Errorf("failed to create workflow registry client: %w", err)
return
}
h.wrc = wrc
}()

return &h
return nil
}

func (h *handler) ResolveInputs(v *viper.Viper) (Inputs, error) {
Expand All @@ -137,11 +138,16 @@ func (h *handler) ValidateInputs(in Inputs) error {
return nil
}

func (h *handler) Execute(in Inputs) error {
func (h *handler) Execute(ctx context.Context, in Inputs) error {
if !h.validated {
return fmt.Errorf("inputs not validated")
}

h.execCtx = ctx
if err := h.initWorkflowRegistryClient(); err != nil {
return err
}

h.displayDetails()

ui.Dim(fmt.Sprintf("Starting unlinking: owner=%s", in.WorkflowOwner))
Expand Down Expand Up @@ -181,7 +187,7 @@ func (h *handler) Execute(in Inputs) error {
}
}

resp, err := h.callInitiateUnlinking(context.Background(), in)
resp, err := h.callInitiateUnlinking(h.execCtx, in)
if err != nil {
return err
}
Expand Down Expand Up @@ -255,10 +261,10 @@ func (h *handler) unlinkOwner(owner string, resp initiateUnlinkingResponse) erro
}

addr := common.HexToAddress(owner)
if err := h.wrc.CanUnlinkOwner(addr, ts, sigBytes); err != nil {
if err := h.wrc.CanUnlinkOwner(h.execCtx, addr, ts, sigBytes); err != nil {
return fmt.Errorf("unlink request verification failed: %w", err)
}
txOut, err := h.wrc.UnlinkOwner(addr, ts, sigBytes)
txOut, err := h.wrc.UnlinkOwner(h.execCtx, addr, ts, sigBytes)
if err != nil {
return fmt.Errorf("UnlinkOwner failed: %w", err)
}
Expand Down Expand Up @@ -346,7 +352,7 @@ func (h *handler) unlinkOwner(owner string, resp initiateUnlinkingResponse) erro
func (h *handler) checkIfAlreadyLinked() (bool, error) {
ownerAddr := common.HexToAddress(h.settings.Workflow.UserWorkflowSettings.WorkflowOwnerAddress)

linked, err := h.wrc.IsOwnerLinked(ownerAddr)
linked, err := h.wrc.IsOwnerLinked(h.execCtx, ownerAddr)
if err != nil {
return false, fmt.Errorf("failed to check owner link status: %w", err)
}
Expand Down
7 changes: 4 additions & 3 deletions cmd/client/client_factory.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package client

import (
"context"
"fmt"
"strings"

Expand All @@ -15,7 +16,7 @@ import (
)

type Factory interface {
NewWorkflowRegistryV2Client() (*WorkflowRegistryV2Client, error)
NewWorkflowRegistryV2Client(ctx context.Context) (*WorkflowRegistryV2Client, error)
GetTxType() TxType
GetSkipConfirmation() bool
}
Expand All @@ -32,7 +33,7 @@ func NewFactory(logger *zerolog.Logger, viper *viper.Viper) Factory {
}
}

func (f *factoryImpl) NewWorkflowRegistryV2Client() (*WorkflowRegistryV2Client, error) {
func (f *factoryImpl) NewWorkflowRegistryV2Client(ctx context.Context) (*WorkflowRegistryV2Client, error) {
environmentSet, err := environments.New()
if err != nil {
return nil, fmt.Errorf("failed to load environment details: %w", err)
Expand Down Expand Up @@ -60,7 +61,7 @@ func (f *factoryImpl) NewWorkflowRegistryV2Client() (*WorkflowRegistryV2Client,
txcConfig,
)

typeAndVersion, err := workflowRegistryV2Client.TypeAndVersion()
typeAndVersion, err := workflowRegistryV2Client.TypeAndVersion(ctx)
if err != nil {
return workflowRegistryV2Client, fmt.Errorf("failed to get type and version of workflow registry contract at %s: %w", environmentSet.WorkflowRegistryAddress, err)
}
Expand Down
Loading
Loading