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 ¶
- type Checker
- type Delivery
- type Outcome
- type PolicyLoader
- type Saved
- type Secret
- type Service
- func (s *Service) Deliver(ctx context.Context, appID string, d Delivery) (Outcome, error)
- func (s *Service) Get(ctx context.Context, app state.App) (View, error)
- func (s *Service) RemoveSecret(ctx context.Context, p authz.Principal, app state.App) error
- func (s *Service) RotateSecret(ctx context.Context, p authz.Principal, app state.App) (Secret, error)
- func (s *Service) Set(ctx context.Context, p authz.Principal, app state.App, ad spec.AutoDeploy) (Saved, error)
- type View
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
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 ¶
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 ¶
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
Audit func(ctx context.Context, e audit.Event)
Logger *zap.Logger
}
Service reads and changes auto-deploy settings, and takes webhooks.
func (*Service) Deliver ¶
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) RemoveSecret ¶
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.