Documentation
¶
Overview ¶
Package static is the static release channel's shared shape (spec 0203): the two documents a release publishes to a plain HTTPS location, one pointer to the current release and one immutable manifest per tag, and the layout that places them. The writer (cmd/releasemanifest) and the reader (the updater's static branch) share these types so they cannot drift; the schema version is the contract with any publisher that is not our tool.
Index ¶
- Constants
- Variables
- func FileURL(base, tag, name string) string
- func ManifestURL(base, tag string) string
- func PointerURL(base string) string
- type Channel
- func (c *Channel) BaseURL() string
- func (c *Channel) ByTag(ctx context.Context, tag string) (Manifest, error)
- func (c *Channel) Fetch(ctx context.Context, rawURL string, maxBytes int64) ([]byte, error)
- func (c *Channel) Latest(ctx context.Context) (Manifest, error)
- func (c *Channel) List(ctx context.Context, limit int) ([]Manifest, error)
- func (c *Channel) Open(ctx context.Context, rawURL string) (io.ReadCloser, error)
- func (c *Channel) Pointer(ctx context.Context) (Pointer, error)
- type Download
- type Manifest
- type Pointer
Constants ¶
const ( MaxPointerBytes = 64 << 10 MaxManifestBytes = 1 << 20 // DefaultListLimit is the page List returns for limit <= 0, a match for // the forge providers' first page so callers see the same shape. DefaultListLimit = 30 )
Bounds on the channel's documents. The pointer is five fields; a manifest grows with its download list and notes. A body past the bound is refused rather than read, so a mis-served object cannot be made into a memory bill.
const ( PointerFile = "latest.json" ManifestFile = "release.json" ChecksumsFile = "checksums.txt" SignatureFile = "checksums.txt.sig" )
The fixed file names: PointerFile under the base URL, the rest under a tag's directory. ChecksumsFile and SignatureFile are goreleaser's defaults and the layout reference's names; the manifest carries their URLs, so a reader never assumes them.
const SchemaVersion = 1
SchemaVersion is the document schema this package writes and the highest it reads. A reader refuses a value it does not know rather than guessing.
Variables ¶
var ( // ErrInvalidBaseURL: the configured base is not an absolute http(s) URL. ErrInvalidBaseURL = errors.NewSentinel("gtb.release.static.invalid_base_url", "release channel base URL must be an absolute http(s) URL") // ErrNoReleasesPublished: the pointer does not exist yet. ErrNoReleasesPublished = errors.NewSentinel("gtb.release.static.no_releases_published", "no release has been published on this channel yet") // ErrReleaseNotFound: no manifest for the tag asked for. ErrReleaseNotFound = errors.NewSentinel("gtb.release.static.release_not_found", "no release with that tag on this channel") // ErrNotFound: an object a manifest names is not there. ErrNotFound = errors.NewSentinel("gtb.release.static.not_found", "the channel has no such object") // ErrBrokenChain: a manifest the pointer or a previous link names does not // resolve, or the chain loops. ErrBrokenChain = errors.NewSentinel("gtb.release.static.broken_chain", "the release chain does not resolve") // ErrTooLarge: a document exceeded its bound. ErrTooLarge = errors.NewSentinel("gtb.release.static.too_large", "a channel document exceeded its size bound") // ErrUnexpectedStatus: a status that is neither success nor 404. ErrUnexpectedStatus = errors.NewSentinel("gtb.release.static.unexpected_status", "the channel answered with an unexpected HTTP status") )
Sentinels the reader answers with, namespaced gtb.release.static.
var ( // ErrUnsupportedSchema is a document whose schema this reader does not know. ErrUnsupportedSchema = errors.NewSentinel("gtb.release.static.unsupported_schema", "unsupported release manifest schema") // ErrEscapesBase is a URL in a document that is not under the channel's // base URL: a manifest cannot send the tool to a host the author did not name. ErrEscapesBase = errors.NewSentinel("gtb.release.static.escapes_base", "release manifest names a URL outside the channel's base") // ErrInvalidManifest is a document that parses but is not well formed. ErrInvalidManifest = errors.NewSentinel("gtb.release.static.invalid_manifest", "release manifest is not well formed") )
Sentinels, namespaced gtb.release.static.
Functions ¶
func ManifestURL ¶
ManifestURL is where tag's manifest lives under base.
func PointerURL ¶
PointerURL is where the pointer lives under base.
Types ¶
type Channel ¶
type Channel struct {
// contains filtered or unexported fields
}
Channel reads a static release channel (spec 0203 D4): the pointer, the manifests it chains to, and the files they name. It knows one base URL and trusts nothing that would take it off it, redirects included.
func New ¶
New builds a reader over base. client is copied so its redirect policy can be replaced; nil means http.DefaultClient's transport.
func (*Channel) ByTag ¶
ByTag is one release's manifest, fetched directly. It never reads the pointer, so a pinned version costs one request.
func (*Channel) Fetch ¶
Fetch reads one object a manifest names, bounded by maxBytes. The URL must be under the base, as every URL in a valid manifest is.
func (*Channel) List ¶
List walks the chain from the latest release, newest first, up to limit manifests (DefaultListLimit for limit <= 0). A link that does not resolve or a chain that loops ends the walk with ErrBrokenChain and whatever was read before it.
type Download ¶
type Download struct {
OS string `json:"os"`
Arch string `json:"arch"`
Name string `json:"name"`
URL string `json:"url"`
Size int64 `json:"size"`
SHA256 string `json:"sha256"`
}
Download is one archive for one platform. OS and Arch are Go's GOOS and GOARCH; SHA256 is the hex digest checksums.txt also carries.
type Manifest ¶
type Manifest struct {
Schema int `json:"schema"`
Tool string `json:"tool"`
Tag string `json:"tag"`
ReleasedAt string `json:"released_at"`
Previous string `json:"previous"`
Checksums string `json:"checksums"`
Signature string `json:"signature,omitempty"`
Notes string `json:"notes,omitempty"`
Downloads []Download `json:"downloads"`
}
Manifest is <base>/<tag>/release.json: everything a tool needs to retrieve and verify one release, plus the previous tag so the manifests form a chain a reader can walk without a listing.
func DecodeManifest ¶
DecodeManifest parses and validates a manifest fetched from under base.
type Pointer ¶
type Pointer struct {
Schema int `json:"schema"`
Tool string `json:"tool"`
Tag string `json:"tag"`
Manifest string `json:"manifest"`
PublishedAt string `json:"published_at"`
}
Pointer is <base>/latest.json: the one object on the channel that changes after it is written. It names the current release and where its manifest is.
func DecodePointer ¶
DecodePointer parses and validates a pointer fetched from under base.