actionrpc

package
v1.21.0 Latest Latest
Warning

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

Go to latest
Published: Oct 9, 2026 License: MIT Imports: 22 Imported by: 0

Documentation

Overview

Package actionrpc is the protocol between the workflow runner and its actions. Each action runs in a process of its own, started from the probe binary, and is called over go-plugin's gRPC transport.

Index

Constants

View Source
const (
	// KindReadOnly is ReadOnly: the action refuses what writes.
	KindReadOnly = "read-only"
	// KindAllowHost is AllowHosts: the action refuses a host the guard does
	// not allow.
	KindAllowHost = "allow-host"
)

The kinds of guard, as an action declares the ones it keeps to.

Variables

View Source
var (
	// BuiltinCmd is the subcommand of the probe binary that serves an action.
	BuiltinCmd = "builtin-actions"
	// Handshake is the go-plugin handshake both sides of an action agree on.
	Handshake = plugin.HandshakeConfig{ProtocolVersion: 1, MagicCookieKey: "probe", MagicCookieValue: "actions"}
	// PluginMap is the set of plugins the runner can dispense.
	PluginMap = map[string]plugin.Plugin{"actions": &Plugin{}}
)

Functions

func IsRefused added in v1.20.0

func IsRefused(err error) bool

IsRefused reports whether err is, or wraps, a Refused error.

func LogOutcome

func LogOutcome(log hclog.Logger, subject string, ret map[string]any, err error)

LogOutcome records how an action finished. subject names what was attempted, for example "http request", and is used to build the message.

func LogParams

func LogParams(log hclog.Logger, msg string, with map[string]any)

LogParams records the parameters an action received, truncating long values so that a large request body does not flood the log. Actions are separate processes, so their log records reach the workflow runner as JSON on stderr and are re-filtered there by the runner's own level.

func Refuse added in v1.20.0

func Refuse(format string, args ...any) error

Refuse returns a Refused error with the reason formatted.

func Run

func Run(name string, with map[string]any, log hclog.Logger) (map[string]any, error)

Run starts the action named name from the running probe binary, calls it once with the given parameters, and stops it. The action's own log records reach log, which decides what of them is shown.

func RunExecutable added in v1.17.0

func RunExecutable(path string, sum []byte, with map[string]any, log hclog.Logger) (map[string]any, error)

RunExecutable starts the action served by the executable at path, calls it once with the given parameters, and stops it, as Run does for a built-in one. When sum is not empty, the executable is started only if its SHA-256 digest is sum.

func RunExecutableStep added in v1.19.0

func RunExecutableStep(path string, sum []byte, call Call, log hclog.Logger) (map[string]any, map[string]any, error)

RunExecutableStep is RunExecutable for a step, as RunStep is Run for one.

func RunStep added in v1.19.0

func RunStep(name string, call Call, log hclog.Logger) (map[string]any, map[string]any, error)

RunStep is Run for a step: the action is told about the step and given the state it left in the job, and the state it leaves is returned, which is nil when it keeps none.

func Sendable added in v1.19.0

func Sendable(v map[string]any) (map[string]any, error)

Sendable returns a copy of v as an action in a process of its own sends it and the runner receives it: maps keyed by strings, lists, and plain values, with whole numbers as int64. The maps and lists are new, so the copy shares none of them with v. It fails for a value that cannot be sent, as sending it would.

func Serve

func Serve(newAction func(log hclog.Logger) Action)

Serve serves the action that newAction builds to the workflow runner that started this process, and returns once the runner is done with it. The action logs through the logger it is given, which writes JSON to stderr for the runner to filter.

Types

type Action

type Action interface {
	Run(with map[string]any) (map[string]any, error)
}

Action is what an action implements: it runs once with the step's `with` parameters and returns its result.

type Call added in v1.19.0

type Call struct {
	// With holds the step's with parameters, as Action.Run is given them.
	With map[string]any
	// State is the state the action left in the job, or nil when it left
	// none. The runner keeps the state the action returns without reading
	// it, and gives it to the action again in the next step of the job that
	// uses it. The state starts empty in each run of a job, and a nil state
	// returned keeps it as it was.
	State map[string]any
	// Step is the step the action runs for.
	Step Step
	// Guard is what the run allows the action to do. An action that keeps
	// to it returns a Refused error for what it does not allow.
	Guard Guard
}

Call is what a StepAction is given to run once for a step.

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client calls an Action in another process.

func (*Client) Run

func (m *Client) Run(with map[string]any) (map[string]any, error)

Run calls the action with the given parameters.

func (*Client) RunStep added in v1.19.0

func (m *Client) RunStep(call Call) (map[string]any, map[string]any, error)

RunStep calls the action for a step, and returns the state it leaves, which is nil when the action keeps none. An action that is not a StepAction is run with the parameters alone.

type Guard added in v1.20.0

type Guard struct {
	// ReadOnly allows only what reads, and nothing that writes, such as an
	// HTTP POST or an UPDATE.
	ReadOnly bool
	// AllowHosts are the hosts actions may connect to: a name or an address,
	// with a port or without one for any port, or *.example.com for the
	// names under example.com. Empty allows any host.
	AllowHosts []string
	// AllowActions are the actions run under the guard although they do not
	// keep to it, as the person running probe asks.
	AllowActions []string
	// Keeps holds the kinds of guard each action says it keeps to itself,
	// keyed by the action as a step's uses names it: a built-in action by
	// what its package declares, an external one by its action.yml. An
	// action is refused under a guard it does not keep to every kind of,
	// unless AllowActions names it.
	Keeps map[string][]string
}

Guard is what a run allows its actions to do. It is set by whoever runs probe, on the command line, rather than by the workflow, so that a workflow cannot loosen it. The zero Guard allows everything.

A guard keeps a workflow from writing to, or reaching, what it was not meant to; it is not a sandbox. An action keeps to it only as far as the action can tell what it is about to do.

func (Guard) Active added in v1.20.0

func (g Guard) Active() bool

Active reports whether the guard limits anything.

func (Guard) AllowsHost added in v1.20.0

func (g Guard) AllowsHost(hostport string) bool

AllowsHost reports whether the guard allows connecting to hostport, a host with or without a port.

func (Guard) CheckHost added in v1.20.0

func (g Guard) CheckHost(hostport string) error

CheckHost returns a Refused error when the guard does not allow connecting to hostport.

func (Guard) Kinds added in v1.21.0

func (g Guard) Kinds() []string

Kinds returns the kinds of guard that limit the run, in the order of the constants.

func (Guard) Missing added in v1.21.0

func (g Guard) Missing(uses string) []string

Missing returns the kinds of guard that limit the run and that the action named uses does not keep to.

func (Guard) Runs added in v1.20.0

func (g Guard) Runs(uses string) bool

Runs reports whether the action named uses may run under the guard: it keeps to every kind of guard that limits the run, or the person running probe allowed it.

func (Guard) WithKeeps added in v1.21.0

func (g Guard) WithKeeps(uses string, kinds []string) Guard

WithKeeps returns a copy of the guard that also holds that the action named uses keeps to kinds, leaving the guard it was made from as it was.

type Plugin

type Plugin struct {
	plugin.Plugin
	Impl Action
}

Plugin serves an Action over gRPC, and is what the runner dispenses to call one.

func (*Plugin) GRPCClient

func (p *Plugin) GRPCClient(ctx context.Context, broker *plugin.GRPCBroker, c *grpc.ClientConn) (any, error)

func (*Plugin) GRPCServer

func (p *Plugin) GRPCServer(broker *plugin.GRPCBroker, s *grpc.Server) error

type Refused added in v1.20.0

type Refused struct {
	Reason string
}

Refused is the error an action returns for what the guard of the run does not allow. The runner tells it from other errors of an action.

func (*Refused) Error added in v1.20.0

func (r *Refused) Error() string

type Server

type Server struct {
	Impl Action
	// contains filtered or unexported fields
}

Server answers the runner's calls with an Action.

func (*Server) Run

func (m *Server) Run(ctx context.Context, req *pb.RunRequest) (*pb.RunResponse, error)

Run runs the action with the request's parameters.

type Step added in v1.19.0

type Step struct {
	// RunID names the run of probe, the same for every step of every job in
	// it, and for a job run by the embedded action.
	RunID   string
	JobID   string
	JobName string
	// Index is the position of the step in the job, from 0.
	Index int
	// ID is the id the step is given, or empty.
	ID   string
	Name string
	// Repeat is which run of a repeated job this is, from 0.
	Repeat int
	// Attempt is which attempt of a retried step this is, from 1.
	Attempt int
}

Step tells an action about the step it runs for.

type StepAction added in v1.19.0

type StepAction interface {
	Action
	RunStep(call Call) (result, newState map[string]any, err error)
}

StepAction is an Action that is told about the step it runs for, and may keep state in a job from one step that uses it to the next, such as the cookies a server set. What it does with either is up to the action.

Jump to

Keyboard shortcuts

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