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

announce

package
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Oct 31, 2026 License: Apache-2.0 Imports: 17 Imported by: 0

Documentation

Overview

Package announce fetches Flowi's announcements: a short list of notices from the project, shown at startup and by `flowi news`.

The feed is a JSON document {"payload": base64, "signature": base64} whose signature is an Ed25519 signature of the decoded payload. Only a feed signed by a configured key is shown, whatever served it. The fetch is quiet by design: it has a short timeout, caches the last good feed, never follows redirects and, when anything goes wrong, still returns what the cache holds along with the reason.

Nothing is fetched unless a feed URL and at least one trusted key are configured; there is no built-in address.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrBadSignature  = errors.New("announcements: the feed is not signed by a trusted key")
	ErrTooLarge      = errors.New("announcements: the feed is too large")
	ErrRollback      = errors.New("announcements: the feed is older than the one already held")
	ErrMalformed     = errors.New("announcements: the feed is malformed")
	ErrNotConfigured = errors.New("announcements: no feed is configured")
	ErrNoKeys        = errors.New("announcements: a feed is configured but no trusted key")
	ErrTurnedOff     = errors.New("announcements: turned off")
	ErrBadKey        = errors.New("announcements: not a valid trusted key")
)

Errors a fetch can report.

Functions

func ParseKey

func ParseKey(s string) (ed25519.PublicKey, error)

ParseKey reads a base64 Ed25519 public key.

func Sign

func Sign(priv ed25519.PrivateKey, issued time.Time, items []Item) ([]byte, error)

Sign builds the feed document a publisher hosts: items issued at the given time, signed with priv. Publishing tools and tests use it.

Types

type Config

type Config struct {
	URL       string
	Keys      []ed25519.PublicKey
	CacheFile string
	TTL       time.Duration // how long a cached feed is used without asking again; default 6h
	Timeout   time.Duration // for the whole request; default 3s
	Client    *http.Client  // nil → a client with Timeout that does not follow redirects
	Now       func() time.Time
}

Config configures a Feed.

func ConfigFrom

func ConfigFrom(r settings.Resolved, cacheFile string) (cfg Config, on bool, err error)

ConfigFrom reads the announcements settings. on is false when the toggle is off or no feed URL is set, which is the default: nothing is fetched. A URL without a usable key is an error, not a silent skip, since showing unsigned text is exactly what the keys exist to prevent.

type Feed

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

Feed fetches and caches the announcements. It is safe for concurrent use in the sense that it holds no state beyond its cache file, which is replaced atomically.

func New

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

New checks the configuration. The URL must be https (plain http only for loopback, for tests and local mirrors) and at least one key is required.

func (*Feed) Fetch

func (f *Feed) Fetch(ctx context.Context) (Result, error)

Fetch returns the current announcements. A fresh cache is used without touching the network. Otherwise the feed is fetched, verified and cached; if that fails, the cached feed (if it verifies) is returned as Stale together with the error, which callers normally log and ignore.

type Item

type Item struct {
	ID    string    `json:"id"`
	Title string    `json:"title"`
	Body  string    `json:"body,omitempty"`
	URL   string    `json:"url,omitempty"`   // https only
	Level string    `json:"level,omitempty"` // info | warning
	Until time.Time `json:"until,omitempty"` // zero: no end
}

Item is one announcement, already cleaned for display.

type Result

type Result struct {
	Items  []Item
	Stale  bool
	Issued time.Time
}

Result is what a fetch found. Stale means the items come from the cache because a fresh feed could not be had.

func Load

func Load(ctx context.Context, r settings.Resolved, cacheFile string, refresh bool) (Result, error)

Load fetches the announcements the settings ask for: ErrTurnedOff when the announcements toggle is off, ErrNotConfigured when no feed URL is set, otherwise as Feed.Fetch. refresh ignores a recent cache.

Jump to

Keyboard shortcuts

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