* Create a MultiPublisher
MultiPublisher mimics io.MultiWriter in that it will publish an image to
multiple publish.Interface implementations.
* Add publish.{Tarball,Layout}Publisher
This adds support for publishing in the tarball format and to an OCI
image layout.
The tarball format isn't great, yet. It only supports writing once
instead of appending.
* Consolidate options
These were spread all over the place for no reasons. Now all the
publisher related options are grouped together.
* Add options for tarball/layout
Adds --oci-layout-path, --tarball, and --push flags.
--push=false will disable the default behavior of publishing to a
registry.
* go mod vendor
* Add Close method to publish.Interface
This allows us to defer writing to the tarball until we've collected all
the images that have been published.
* Fix tests
When resolving files, we would just log.Fatal if we encountered an
error. This seems to be racy and causes ko to exit with a 0 error code
when it shouldn't. To fix this, we synchronize the builder goroutines
with the kubectl go routine and exit with an error if either of them
failed.
This fix also happened to fix a goroutine leak. If the kubectl goroutine
failed, we never properly cancelled the builds, which would happily
conitnue compiling packages and consuming resources.
* Add build.Limiter
You can limit the number of concurrent builds with -j (a la make).
The default value for this is GOMAXPROCS, which seems reasonable.
When ko is invoked in this mode, import paths must have the `ko://`
prefix. If a human marks an import path with `ko://` and ko can't
resolve the resulting import path, it fails. In "loose mode", such an
import path would be silently ignored and passed on to the resolved
YAML, often resulting in invalid image names (e.g., `image:
github.com/foo/bar`)
In loose mode, `ko://` prefixes are always ignored for
backward-compatibility.
This hoists the publisher creation out of the loop for `ko publish` to
avoid needlessly resolving credentials multiple times.
This pulls the publisher creation outside of resolveFilesToWriter so we
can fail earlier if e.g. KO_DOCKER_REPO is unset, otherwise we start up
the kubectl goroutine and it would asynchronously fail with:
error: no objects passed to apply