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

autodeploy

package
v0.14.0 Latest Latest
Warning

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

Go to latest
Published: Oct 23, 2026 License: AGPL-3.0 Imports: 21 Imported by: 0

Documentation

Overview

Package autodeploy is the service behind an app's automatic deploy settings and its webhook (R-141, R-142).

The settings live in the spec, so changing them writes a revision the next deploy ships, as every other edit does (R-152). What this adds is one place every client changes them through — the console, the CLI and MCP all call the same endpoints (R-261) — and the per-app webhook a git host calls to make the next check happen now rather than at the next poll.

The webhook starts nothing a poll could not. It is verified, and then it asks the auto-deploy job to check the app (reconciler.AutoDeploy.CheckApp), which reads the watched ref itself and goes the ordinary way. What the request says about commits is never trusted: a forged payload naming a commit cannot ship it.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Checker

type Checker interface {
	CheckApp(ctx context.Context, appID, delivery string) error
}

Checker checks one app for something new to deploy, now.

type Delivery

type Delivery struct {
	// Event is the X-GitHub-Event header: push, release, create or ping.
	Event string

	// Signature is the X-Hub-Signature-256 header: "sha256=" and the hex
	// HMAC-SHA256 of Body, keyed by the app's webhook secret.
	Signature string

	Body []byte
}

Delivery is one webhook request from a git host, as it arrived.

type Outcome

type Outcome struct {
	// Checking is whether the delivery started a check. It never deploys
	// directly; the check decides.
	Checking bool   `json:"checking"`
	Message  string `json:"message"`
}

Outcome is what Pando did with a webhook.

type PolicyLoader

type PolicyLoader interface {
	Load(ctx context.Context) (policy.Document, error)
}

PolicyLoader reads host policy as it is now.

type Saved

type Saved struct {
	Changed  bool   `json:"changed"`
	Revision int    `json:"revision,omitempty"`
	SpecID   string `json:"spec_id,omitempty"`
}

Saved is the outcome of Set.

type Secret

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

Secret is a webhook secret, shown once (R-194 holds everywhere else: the one response that carries it marshals it in the clear, on purpose).

func (Secret) MarshalJSON

func (k Secret) MarshalJSON() ([]byte, error)

type Service

type Service struct {
	Apps    *state.Apps
	Checks  *state.AutoDeployChecks
	Secrets *state.AutoDeploySecrets
	Policy  PolicyLoader

	// Authz is what the spec gate asks (R-158, R-184).
	Authz specgate.Authorizer

	// Checker is the auto-deploy job.
	Checker Checker

	// Sources holds the webhook secrets of source connections with a webhook
	// of their own: a GitHub App Pando created (DeliverForSource).
	Sources WebhookSecretReader

	Audit  func(ctx context.Context, e audit.Event)
	Logger *zap.Logger
}

Service reads and changes auto-deploy settings, and takes webhooks.

func (*Service) Deliver

func (s *Service) Deliver(ctx context.Context, appID string, d Delivery) (Outcome, error)

Deliver verifies a webhook and, when it concerns what the app watches, starts a check (R-142). The check runs in the background: a git host times a webhook out after a few seconds, and a missed one costs nothing, since the poll still runs.

Every refusal is the same refusal, whatever the reason — no such app, no secret, a wrong signature — so the endpoint does not tell a stranger which app IDs exist or which have a webhook.

func (*Service) DeliverForSource added in v0.11.0

func (s *Service) DeliverForSource(ctx context.Context, sourceID string, d Delivery) (Outcome, error)

DeliverForSource takes a webhook a source connection's own webhook was sent — a GitHub App Pando created, which hears every repository it is installed on (R-142) — and starts a check of each app that deploys automatically from the repository it names and that the delivery concerns. As with an app's own webhook, the payload only says which apps to check now; each check reads the watched ref itself.

A delivery that cannot be verified is refused the same way whatever the reason, so the endpoint does not tell a stranger which connections exist.

func (*Service) Get

func (s *Service) Get(ctx context.Context, app state.App) (View, error)

Get is an app's auto-deploy settings, last check and webhook.

func (*Service) RemoveSecret

func (s *Service) RemoveSecret(ctx context.Context, p authz.Principal, app state.App) error

RemoveSecret removes the app's webhook secret, which turns its webhook off. Polling carries on.

func (*Service) RotateSecret

func (s *Service) RotateSecret(ctx context.Context, p authz.Principal, app state.App) (Secret, error)

RotateSecret makes the app a new webhook secret, replacing any it had, and returns it — the only time it is shown. The old one stops verifying at once.

func (*Service) Set

func (s *Service) Set(ctx context.Context, p authz.Principal, app state.App, ad spec.AutoDeploy) (Saved, error)

Set changes an app's auto-deploy settings: a new revision built on the newest one, which the next deploy ships (R-152). The same validation and the same gate as any spec save, so a setting refused there is refused here in the same words (R-158).

type View

type View struct {
	// Settings are the newest revision's: what the next deploy ships.
	Settings spec.AutoDeploy `json:"settings"`

	// Deployed are the pinned revision's: what is in effect now.
	Deployed spec.AutoDeploy `json:"deployed"`

	// Pending is whether Settings are saved and not yet deployed.
	Pending bool `json:"pending"`

	// Paused is whether approval now stops an app that auto-deploys (R-158).
	Paused bool `json:"paused"`

	// LastCheck is the last time auto-deploy looked, or nil if it has not.
	LastCheck *state.AutoDeployCheck `json:"last_check"`

	// WebhookSecretSet is whether the app has a webhook secret, and so
	// whether its webhook does anything. The secret itself is shown once,
	// when it is made.
	WebhookSecretSet bool `json:"webhook_secret_set"`

	// WebhookURL is where the git host sends webhooks. The HTTP layer fills
	// it in, since only it knows the address Pando is reached at.
	WebhookURL string `json:"webhook_url"`
}

View is an app's auto-deploy as the API shows it.

type WebhookSecretReader added in v0.11.0

type WebhookSecretReader interface {
	WebhookSecret(ctx context.Context, id string) (secret.Value, bool, error)
}

WebhookSecretReader reads the secret a source connection's own webhook is signed with (sourceconn.Service.WebhookSecret).

Jump to

Keyboard shortcuts

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