operations

package
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 18, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package operations provides CRE workflow operations that execute side effects via the CRE CLI.

Index

Constants

View Source
const (
	// CREDeployTargetName is the workflow.yaml / project.yaml target key used for this layout.
	CREDeployTargetName = "cld-deploy"
)

Variables

View Source
var CREWorkflowDeleteOp = fwops.NewOperation(
	"cre-workflow-delete",
	semver.MustParse("1.0.0"),
	"Deletes a CRE workflow via the CRE CLI subprocess",
	func(b fwops.Bundle, deps CREDeployDeps, input CREWorkflowDeleteInput) (CREWorkflowDeleteOutput, error) {
		ctx := b.GetContext()
		if deps.CLI == nil {
			return CREWorkflowDeleteOutput{}, errors.New("cre CLIRunner is nil")
		}

		workDir, err := os.MkdirTemp("", "cre-workflow-delete-*")
		if err != nil {
			return CREWorkflowDeleteOutput{}, fmt.Errorf("mkdir temp workflow delete workspace: %w", err)
		}
		defer func() { _ = os.RemoveAll(workDir) }()

		resolver, err := creartifacts.NewArtifactsResolver(workDir)
		if err != nil {
			return CREWorkflowDeleteOutput{}, err
		}

		bundleDir := filepath.Join(workDir, creBundleSubdir)
		if err = os.MkdirAll(bundleDir, 0o700); err != nil {
			return CREWorkflowDeleteOutput{}, err
		}

		projectSrc, err := resolver.ResolveConfig(ctx, input.Project)
		if err != nil {
			return CREWorkflowDeleteOutput{}, fmt.Errorf("resolve project.yaml: %w", err)
		}
		projectDest := filepath.Join(workDir, "project.yaml")
		if err = copyFile(projectSrc, projectDest); err != nil {
			return CREWorkflowDeleteOutput{}, fmt.Errorf("copy project.yaml: %w", err)
		}

		target := input.resolveTargetName()
		workflowCfg := crecli.WorkflowConfig{
			target: {
				UserWorkflow: crecli.UserWorkflow{
					DeploymentRegistry: input.DeploymentRegistry,
					WorkflowName:       input.WorkflowName,
				},
				WorkflowArtifacts: crecli.WorkflowArtifacts{
					WorkflowPath: ".",
					ConfigPath:   "",
					SecretsPath:  "",
				},
			},
		}
		workflowYAMLPath, err := crecli.WriteWorkflowYAML(bundleDir, workflowCfg)
		if err != nil {
			return CREWorkflowDeleteOutput{}, fmt.Errorf("write workflow.yaml: %w", err)
		}

		ctxCfg, err := crecli.BuildContextConfig(input.DonFamily, input.Context, deps.CRECfg, deps.CLI.ContextRegistries())
		if err != nil {
			return CREWorkflowDeleteOutput{}, err
		}
		contextPath, err := crecli.WriteContextYAML(workDir, ctxCfg)
		if err != nil {
			return CREWorkflowDeleteOutput{}, fmt.Errorf("write context.yaml: %w", err)
		}
		logResolvedFile(b.Logger, "workflow.yaml", workflowYAMLPath, prettyYAML)
		logResolvedFile(b.Logger, "project.yaml", projectDest, prettyYAML)
		logResolvedFile(b.Logger, "context.yaml", contextPath, prettyYAML)

		envPath, err := crecli.WriteCREEnvFile(workDir, contextPath, deps.CRECfg, input.DonFamily)
		if err != nil {
			return CREWorkflowDeleteOutput{}, fmt.Errorf("write CRE .env file: %w", err)
		}

		args := BuildWorkflowDeleteArgs(target, workDir, envPath, input.ExtraCREArgs)
		b.Logger.Infow("Running CRE workflow delete", "args", args)

		var runEnv map[string]string
		if crecli.IsOnChainRegistry(input.DeploymentRegistry, crecli.FlatRegistries(ctxCfg)) {
			runEnv = map[string]string{
				"CRE_ETH_PRIVATE_KEY": deps.EVMDeployerKey,
			}
		}
		res, runErr := deps.CLI.Run(ctx, runEnv, args...)
		if runErr != nil {
			var exitErr *fcre.ExitError
			if errors.As(runErr, &exitErr) {
				return CREWorkflowDeleteOutput{
					ExitCode: exitErr.ExitCode,
					Stdout:   string(exitErr.Stdout),
					Stderr:   string(exitErr.Stderr),
				}, fmt.Errorf("cre workflow delete: %w", runErr)
			}

			return CREWorkflowDeleteOutput{}, fmt.Errorf("cre workflow delete: %w", runErr)
		}
		if res == nil {
			return CREWorkflowDeleteOutput{}, errors.New("cre workflow delete: CLI returned nil result without error")
		}

		b.Logger.Infow("CRE workflow delete finished",
			"exitCode", res.ExitCode,
			"stdout", string(res.Stdout),
			"stderr", string(res.Stderr),
		)

		return CREWorkflowDeleteOutput{
			ExitCode: res.ExitCode,
			Stdout:   string(res.Stdout),
			Stderr:   string(res.Stderr),
		}, nil
	},
)

CREWorkflowDeleteOp deletes a workflow via the CRE CLI (single side effect: CLI invocation).

View Source
var CREWorkflowDeployOp = fwops.NewOperation(
	"cre-workflow-deploy",
	semver.MustParse("1.1.0"),
	"Deploys a CRE workflow via the CRE CLI subprocess",
	func(b fwops.Bundle, deps CREDeployDeps, input CREWorkflowDeployInput) (CREWorkflowDeployOutput, error) {
		ctx := b.GetContext()
		if deps.CLI == nil {
			return CREWorkflowDeployOutput{}, errors.New("cre CLIRunner is nil")
		}

		if usesNamedAPIKeys(deps.CRECfg.Auth.APIKey) && strings.TrimSpace(input.APIKeyName) == "" {
			return CREWorkflowDeployOutput{}, errors.New("cre workflow deploy: apiKeyName is required when CRE_API_KEY is configured as a JSON object of named API keys")
		}

		cli := deps.CLI
		if input.APIKeyName != "" {
			selected, err := deps.CLI.WithNamedAPIKey(input.APIKeyName)
			if err != nil {
				return CREWorkflowDeployOutput{}, fmt.Errorf("select cre api key %q: %w", input.APIKeyName, err)
			}
			cli = selected
		}

		workDir, err := os.MkdirTemp("", "cre-workflow-artifacts-*")
		if err != nil {
			return CREWorkflowDeployOutput{}, fmt.Errorf("mkdir temp workflow artifacts: %w", err)
		}
		defer func() { _ = os.RemoveAll(workDir) }()

		resolver, err := creartifacts.NewArtifactsResolver(workDir)
		if err != nil {
			return CREWorkflowDeployOutput{}, err
		}

		binaryPath, err := resolver.ResolveBinary(ctx, input.Binary)
		if err != nil {
			return CREWorkflowDeployOutput{}, fmt.Errorf("resolve workflow binary: %w", err)
		}

		configPath, err := resolver.ResolveConfig(ctx, input.Config)
		if err != nil {
			return CREWorkflowDeployOutput{}, fmt.Errorf("resolve workflow config: %w", err)
		}

		bundleDir := filepath.Join(workDir, creBundleSubdir)
		if err = os.MkdirAll(bundleDir, 0o700); err != nil {
			return CREWorkflowDeployOutput{}, err
		}

		projectSrc, err := resolver.ResolveConfig(ctx, input.Project)
		if err != nil {
			return CREWorkflowDeployOutput{}, fmt.Errorf("resolve project.yaml: %w", err)
		}
		projectDest := filepath.Join(workDir, "project.yaml")
		if err = copyFile(projectSrc, projectDest); err != nil {
			return CREWorkflowDeployOutput{}, fmt.Errorf("copy project.yaml: %w", err)
		}

		target := input.resolveTargetName()
		workflowCfg := crecli.WorkflowConfig{
			target: {
				UserWorkflow: crecli.UserWorkflow{
					DeploymentRegistry: input.DeploymentRegistry,
					WorkflowName:       input.WorkflowName,
				},
				WorkflowArtifacts: crecli.WorkflowArtifacts{
					WorkflowPath: ".",
					ConfigPath:   filepath.Base(configPath),
					SecretsPath:  "",
				},
			},
		}
		workflowYAMLPath, err := crecli.WriteWorkflowYAML(bundleDir, workflowCfg)
		if err != nil {
			return CREWorkflowDeployOutput{}, fmt.Errorf("write workflow.yaml: %w", err)
		}

		ctxCfg, err := crecli.BuildContextConfig(input.DonFamily, input.Context, deps.CRECfg, cli.ContextRegistries())
		if err != nil {
			return CREWorkflowDeployOutput{}, err
		}
		contextPath, err := crecli.WriteContextYAML(workDir, ctxCfg)
		if err != nil {
			return CREWorkflowDeployOutput{}, fmt.Errorf("write context.yaml: %w", err)
		}
		logResolvedFile(b.Logger, "workflow.yaml", workflowYAMLPath, prettyYAML)
		logResolvedFile(b.Logger, "project.yaml", projectDest, prettyYAML)
		logResolvedFile(b.Logger, "context.yaml", contextPath, prettyYAML)
		logResolvedFile(b.Logger, "config.json", configPath, prettyJSON)

		envPath, err := crecli.WriteCREEnvFile(workDir, contextPath, deps.CRECfg, input.DonFamily)
		if err != nil {
			return CREWorkflowDeployOutput{}, fmt.Errorf("write CRE .env file: %w", err)
		}

		args := BuildWorkflowDeployArgs(target, workDir, envPath, binaryPath, configPath, input.ExtraCREArgs)
		b.Logger.Infow("Running CRE workflow deploy", "args", args)

		var runEnv map[string]string
		if crecli.IsOnChainRegistry(input.DeploymentRegistry, crecli.FlatRegistries(ctxCfg)) {
			runEnv = map[string]string{
				"CRE_ETH_PRIVATE_KEY": deps.EVMDeployerKey,
			}
		}
		res, runErr := cli.Run(ctx, runEnv, args...)
		if runErr != nil {
			var exitErr *fcre.ExitError
			if errors.As(runErr, &exitErr) {
				return CREWorkflowDeployOutput{
					ExitCode: exitErr.ExitCode,
					Stdout:   string(exitErr.Stdout),
					Stderr:   string(exitErr.Stderr),
				}, fmt.Errorf("cre workflow deploy: %w", runErr)
			}

			return CREWorkflowDeployOutput{}, fmt.Errorf("cre workflow deploy: %w", runErr)
		}
		if res == nil {
			return CREWorkflowDeployOutput{}, errors.New("cre workflow deploy: CLI returned nil result without error")
		}

		b.Logger.Infow("CRE workflow deploy finished",
			"exitCode", res.ExitCode,
			"stdout", string(res.Stdout),
			"stderr", string(res.Stderr),
		)

		return CREWorkflowDeployOutput{
			ExitCode: res.ExitCode,
			Stdout:   string(res.Stdout),
			Stderr:   string(res.Stderr),
		}, nil
	},
)

CREWorkflowDeployOp deploys a workflow via the CRE CLI (single side effect: CLI invocation).

Functions

func BuildWorkflowDeleteArgs added in v0.4.0

func BuildWorkflowDeleteArgs(targetName, workDir, envPath string, extra []string) []string

BuildWorkflowDeleteArgs constructs the CRE CLI argument list for `cre workflow delete`.

func BuildWorkflowDeployArgs

func BuildWorkflowDeployArgs(targetName, workDir, envPath, binaryPath, configPath string, extra []string) []string

BuildWorkflowDeployArgs constructs the CRE CLI argument list for `cre workflow deploy`.

Types

type CREDeployDeps

type CREDeployDeps struct {
	CLI    fcre.CLIRunner
	CRECfg cfgenv.CREConfig
	// EVMDeployerKey is the raw hex EVM private key from Onchain.EVM.DeployerKey.
	// Injected into the child process environment as CRE_ETH_PRIVATE_KEY only for on-chain registries.
	EVMDeployerKey string
}

CREDeployDeps holds non-serializable dependencies for the workflow deploy operation.

type CREWorkflowDeleteInput added in v0.4.0

type CREWorkflowDeleteInput struct {
	WorkflowName       string `json:"workflowName" yaml:"workflowName"`
	DonFamily          string `json:"donFamily,omitempty" yaml:"donFamily,omitempty"`
	DeploymentRegistry string `json:"deploymentRegistry,omitempty" yaml:"deploymentRegistry,omitempty"`
	// Project is the path to CRE CLI project.yaml (RPCs, don-family, etc.).
	Project creartifacts.ConfigSource `json:"project" yaml:"project"`
	// Optional - Context overrides CRE_* process env defaults for the generated context.yaml.
	Context crecli.ContextOverrides `json:"context" yaml:"context"`
	// Optional - ExtraCREArgs are appended after built-in workflow delete arguments (e.g. org/tenant flags).
	ExtraCREArgs []string `json:"extraCreArgs,omitempty" yaml:"extraCreArgs,omitempty"`
	// Optional - TargetName is the CRE CLI target key that must match a top-level key
	// in project.yaml. Defaults to CREDeployTargetName ("cld-deploy") when empty.
	TargetName string `json:"targetName,omitempty" yaml:"targetName,omitempty"`
}

CREWorkflowDeleteInput is the resolved input for a CRE workflow delete. Project is resolved via creartifacts.ArtifactsResolver. Binary and config are not used.

func (*CREWorkflowDeleteInput) Validate added in v0.4.0

func (in *CREWorkflowDeleteInput) Validate() error

Validate trims fields and checks required workflow delete inputs.

type CREWorkflowDeleteOutput added in v0.4.0

type CREWorkflowDeleteOutput struct {
	ExitCode int    `json:"exitCode"`
	Stdout   string `json:"stdout"`
	Stderr   string `json:"stderr"`
}

CREWorkflowDeleteOutput is the serializable result of a CRE CLI workflow delete invocation.

type CREWorkflowDeployInput

type CREWorkflowDeployInput struct {
	creartifacts.WorkflowBundle `yaml:",inline"`
	// Project is the path to CRE CLI project.yaml (RPCs, don-family, etc.).
	// Resolved the same way as Binary and Config: local path or GitHub ref.
	Project creartifacts.ConfigSource `json:"project" yaml:"project"`
	// Optional - Context overrides CRE_* process env defaults for the generated context.yaml.
	Context crecli.ContextOverrides `json:"context" yaml:"context"`
	// Optional - ExtraCREArgs are appended after built-in workflow deploy arguments (e.g. org/tenant flags).
	ExtraCREArgs []string `json:"extraCreArgs,omitempty" yaml:"extraCreArgs,omitempty"`
	// Optional - TargetName is the CRE CLI target key that must match a top-level key
	// in project.yaml. Defaults to CREDeployTargetName ("cld-deploy") when empty.
	TargetName string `json:"targetName,omitempty" yaml:"targetName,omitempty"`
	// Optional - APIKeyName selects which CRE API key to use when the runner is
	// configured with multiple named keys (e.g. CRE_API_KEY={"prod":"...","stg":"..."}).
	// Leave empty when the runner is configured with a single key.
	APIKeyName string `json:"apiKeyName,omitempty" yaml:"apiKeyName,omitempty"`
}

CREWorkflowDeployInput is the resolved input for a CRE workflow deploy. Binary, config, and project are resolved via creartifacts.ArtifactsResolver. DeploymentRegistry is inherited from creartifacts.WorkflowBundle.

type CREWorkflowDeployOutput

type CREWorkflowDeployOutput struct {
	ExitCode int    `json:"exitCode"`
	Stdout   string `json:"stdout"`
	Stderr   string `json:"stderr"`
}

CREWorkflowDeployOutput is the serializable result of a CRE CLI deploy invocation.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL