Help us shape the future of Go! Take the 2026 Go Developer Survey

forgerunner

package
v0.2.9 Latest Latest
Warning

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

Go to latest
Published: Sep 1, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package forgerunner implements a lightweight Actions runner for Forgejo and Gitea. It registers with the forge via ConnectRPC, polls for tasks, and executes workflow steps via direct process spawning — no Docker.

This package contains the shared logic. Platform-specific CLI entrypoints live in cmd/ephemerd-runner-forgejo (Forgejo) and cmd/ephemerd-runner-gitea (Gitea).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BuildEnv

func BuildEnv(task *forgerpc.Task, runnerName string) map[string]string

BuildEnv extracts environment variables from a forge task payload. These mirror the GITHUB_* and RUNNER_* variables that GHA sets.

func SecretsFromContext

func SecretsFromContext(task *forgerpc.Task) []string

SecretsFromContext extracts secret values from the task context for masking.

Types

type Command

type Command struct {
	Name   string
	Params map[string]string
	Value  string
}

Command is a parsed workflow command from process stdout.

::name param=val,param2=val2::message

func ParseCommand

func ParseCommand(line string) (*Command, bool)

ParseCommand extracts a workflow command from a log line. Returns nil, false if the line is not a command.

type Config

type Config struct {
	// Platform identifies the forge type ("forgejo" or "gitea").
	Platform string

	// InstanceURL is the forge instance base URL (e.g., "https://codeberg.org").
	InstanceURL string

	// Token is the runner registration token from the forge admin panel.
	Token string

	// Name is the runner display name. Defaults to hostname.
	Name string

	// Labels are the runs-on labels to register (e.g., "ubuntu-latest").
	Labels []string

	// Version is reported to the forge during registration.
	Version string

	// HTTPClient is an optional *http.Client for the ConnectRPC client.
	// If nil, a default client with 30s timeout is used.
	HTTPClient *http.Client

	Log *slog.Logger
}

Config configures a forge runner instance.

type Executor

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

Executor runs a single forge task: parses the workflow, executes steps, and reports results back to the forge.

func NewExecutor

func NewExecutor(client *forgerpc.Client, task *forgerpc.Task, log *slog.Logger) *Executor

NewExecutor creates an executor for a task.

func (*Executor) Run

func (e *Executor) Run(ctx context.Context) error

Run executes the task end-to-end.

type FileCommands

type FileCommands struct {
	Outputs  map[string]string // from GITHUB_OUTPUT
	EnvVars  map[string]string // from GITHUB_ENV
	PathAdds []string          // from GITHUB_PATH
}

FileCommands holds values read from GITHUB_OUTPUT, GITHUB_ENV, and GITHUB_PATH file-based command files after a step executes.

func ParseFileCommands

func ParseFileCommands(outputPath, envPath, pathPath string) (*FileCommands, error)

ParseFileCommands reads the file-based command files written by a step.

type Job

type Job struct {
	Name   string            `yaml:"name"`
	RunsOn RunsOn            `yaml:"runs-on"`
	Steps  []*Step           `yaml:"steps"`
	Env    map[string]string `yaml:"env"`
	If     string            `yaml:"if"`
}

Job is a single job within a workflow.

type LogReporter

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

LogReporter batches log lines and streams them to the forge via UpdateLog.

func NewLogReporter

func NewLogReporter(client *forgerpc.Client, taskID int64, masker *SecretMasker) *LogReporter

NewLogReporter creates a log reporter for the given task.

func (*LogReporter) AddLine

func (r *LogReporter) AddLine(content string)

AddLine appends a timestamped, secret-masked log line.

func (*LogReporter) Close

func (r *LogReporter) Close(ctx context.Context) error

Close flushes remaining lines and sends the final noMore=true signal.

func (*LogReporter) Flush

func (r *LogReporter) Flush(ctx context.Context) error

Flush sends any buffered log lines to the forge.

func (*LogReporter) LineCount

func (r *LogReporter) LineCount() int64

LineCount returns the total number of log lines added.

type Runner

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

Runner registers with a Forgejo or Gitea instance and executes workflow steps directly via process spawning — no Docker dependency.

func New

func New(cfg Config) (*Runner, error)

New creates a forge runner from the given config.

func (*Runner) Run

func (r *Runner) Run(ctx context.Context) error

Run registers the runner, declares labels, and polls for a single task. It blocks until the task is executed or the context is cancelled.

type RunsOn

type RunsOn struct {
	Labels []string
}

RunsOn handles the YAML runs-on field which can be a string or []string.

func (*RunsOn) UnmarshalYAML

func (r *RunsOn) UnmarshalYAML(value *yaml.Node) error

type ScriptResult

type ScriptResult struct {
	ExitCode   int
	Outputs    map[string]string // from GITHUB_OUTPUT file
	EnvChanges map[string]string // from GITHUB_ENV file
	PathAdds   []string          // from GITHUB_PATH file
}

ScriptResult is the outcome of running a script step.

func RunScript

func RunScript(ctx context.Context, step *Step, env map[string]string, workDir string, reporter *LogReporter, masker *SecretMasker) (*ScriptResult, error)

RunScript executes a run: step by writing the script to a temp file, spawning the appropriate shell, and capturing output.

type SecretMasker

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

SecretMasker replaces registered secret values with "***" in log output.

func NewSecretMasker

func NewSecretMasker(secrets []string) *SecretMasker

NewSecretMasker creates a masker with the given secrets. Empty and short (< 3 char) secrets are ignored to avoid false positives.

func (*SecretMasker) AddSecret

func (m *SecretMasker) AddSecret(s string)

AddSecret registers an additional secret for masking.

func (*SecretMasker) Mask

func (m *SecretMasker) Mask(s string) string

Mask replaces all registered secrets in s with "***".

type Step

type Step struct {
	ID               string            `yaml:"id"`
	Name             string            `yaml:"name"`
	Run              string            `yaml:"run"`
	Shell            string            `yaml:"shell"`
	Env              map[string]string `yaml:"env"`
	WorkingDirectory string            `yaml:"working-directory"`
	If               string            `yaml:"if"`
	Uses             string            `yaml:"uses"`
	With             map[string]string `yaml:"with"`
}

Step is a single step within a job.

func (*Step) DisplayName

func (s *Step) DisplayName(index int) string

DisplayName returns the step's name, ID, or a fallback based on content.

type Workflow

type Workflow struct {
	Name string          `yaml:"name"`
	Jobs map[string]*Job `yaml:"jobs"`
}

Workflow is a parsed Actions workflow YAML.

func ParseWorkflow

func ParseWorkflow(data []byte) (*Workflow, error)

ParseWorkflow parses workflow YAML bytes into a Workflow.

Jump to

Keyboard shortcuts

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