mirror of
https://github.com/docker/compose.git
synced 2026-08-03 22:27:30 +00:00
feat(publish): add --annotation flag to docker compose publish
Signed-off-by: Mohataseem Khan <mohataseem89@gmail.com>
This commit is contained in:
parent
5fa0f40c61
commit
094bb807e3
6 changed files with 81 additions and 15 deletions
|
|
@ -20,6 +20,7 @@ import (
|
|||
"context"
|
||||
"errors"
|
||||
"strings"
|
||||
"fmt"
|
||||
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli/command"
|
||||
|
|
|
|||
42
cmd/compose/publish_test.go
Normal file
42
cmd/compose/publish_test.go
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
Copyright 2020 Docker Compose CLI authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package compose
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"gotest.tools/v3/assert"
|
||||
)
|
||||
|
||||
func TestParseAnnotations(t *testing.T) {
|
||||
t.Run("valid annotation", func(t *testing.T) {
|
||||
result, err := parseAnnotations([]string{"foo=bar"})
|
||||
assert.NilError(t, err)
|
||||
assert.DeepEqual(t, result, map[string]string{"foo": "bar"})
|
||||
})
|
||||
|
||||
t.Run("invalid annotation missing equals sign", func(t *testing.T) {
|
||||
_, err := parseAnnotations([]string{"foobar"})
|
||||
assert.Error(t, err, `invalid annotation "foobar": expected format key=value`)
|
||||
})
|
||||
|
||||
t.Run("empty slice", func(t *testing.T) {
|
||||
result, err := parseAnnotations([]string{})
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, result == nil)
|
||||
})
|
||||
}
|
||||
|
|
@ -5,14 +5,15 @@ Publish compose application
|
|||
|
||||
### Options
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:--------------------------|:---------|:--------|:-------------------------------------------------------------------------------|
|
||||
| `--app` | `bool` | | Published compose application (includes referenced images) |
|
||||
| `--dry-run` | `bool` | | Execute command in dry run mode |
|
||||
| `--oci-version` | `string` | | OCI image/artifact specification version (automatically determined by default) |
|
||||
| `--resolve-image-digests` | `bool` | | Pin image tags to digests |
|
||||
| `--with-env` | `bool` | | Include environment variables in the published OCI artifact |
|
||||
| `-y`, `--yes` | `bool` | | Assume "yes" as answer to all prompts |
|
||||
| Name | Type | Default | Description |
|
||||
|:--------------------------|:--------------|:--------|:-------------------------------------------------------------------------------|
|
||||
| `--annotation` | `stringArray` | | Add custom metadata to the published OCI artifact (format: key=value) |
|
||||
| `--app` | `bool` | | Published compose application (includes referenced images) |
|
||||
| `--dry-run` | `bool` | | Execute command in dry run mode |
|
||||
| `--oci-version` | `string` | | OCI image/artifact specification version (automatically determined by default) |
|
||||
| `--resolve-image-digests` | `bool` | | Pin image tags to digests |
|
||||
| `--with-env` | `bool` | | Include environment variables in the published OCI artifact |
|
||||
| `-y`, `--yes` | `bool` | | Assume "yes" as answer to all prompts |
|
||||
|
||||
|
||||
<!---MARKER_GEN_END-->
|
||||
|
|
|
|||
|
|
@ -5,6 +5,17 @@ usage: docker compose alpha publish [OPTIONS] REPOSITORY[:TAG]
|
|||
pname: docker compose alpha
|
||||
plink: docker_compose_alpha.yaml
|
||||
options:
|
||||
- option: annotation
|
||||
value_type: stringArray
|
||||
default_value: '[]'
|
||||
description: |
|
||||
Add custom metadata to the published OCI artifact (format: key=value)
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: app
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
|
|
|
|||
|
|
@ -5,6 +5,17 @@ usage: docker compose publish [OPTIONS] REPOSITORY[:TAG]
|
|||
pname: docker compose
|
||||
plink: docker_compose.yaml
|
||||
options:
|
||||
- option: annotation
|
||||
value_type: stringArray
|
||||
default_value: '[]'
|
||||
description: |
|
||||
Add custom metadata to the published OCI artifact (format: key=value)
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: app
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ func DescriptorForEnvFile(path string, content []byte) v1.Descriptor {
|
|||
}
|
||||
}
|
||||
|
||||
func PushManifest(ctx context.Context, resolver remotes.Resolver, named reference.Named, layers []v1.Descriptor, ociVersion api.OCIVersion) (v1.Descriptor, error) {
|
||||
func PushManifest(ctx context.Context, resolver remotes.Resolver, named reference.Named, layers []v1.Descriptor, ociVersion api.OCIVersion, extraAnnotations map[string]string) (v1.Descriptor, error) {
|
||||
// Check if we need an extra empty layer for the manifest config
|
||||
if ociVersion == api.OCIVersion1_1 || ociVersion == "" {
|
||||
err := push(ctx, resolver, named, v1.DescriptorEmptyJSON)
|
||||
|
|
@ -113,17 +113,17 @@ func PushManifest(ctx context.Context, resolver remotes.Resolver, named referenc
|
|||
|
||||
if ociVersion != "" {
|
||||
// if a version was explicitly specified, use it
|
||||
return createAndPushManifest(ctx, resolver, named, layerDescriptors, ociVersion)
|
||||
return createAndPushManifest(ctx, resolver, named, layerDescriptors, ociVersion, extraAnnotations)
|
||||
}
|
||||
|
||||
// try to push in the OCI 1.1 format but fallback to OCI 1.0 on 4xx errors
|
||||
// (other than auth) since it's most likely the result of the registry not
|
||||
// having support
|
||||
descriptor, err := createAndPushManifest(ctx, resolver, named, layerDescriptors, api.OCIVersion1_1)
|
||||
descriptor, err := createAndPushManifest(ctx, resolver, named, layerDescriptors, api.OCIVersion1_1, extraAnnotations)
|
||||
var pushErr pusherrors.ErrUnexpectedStatus
|
||||
if errors.As(err, &pushErr) && isNonAuthClientError(pushErr.StatusCode) {
|
||||
// TODO(milas): show a warning here (won't work with logrus)
|
||||
return createAndPushManifest(ctx, resolver, named, layerDescriptors, api.OCIVersion1_0)
|
||||
return createAndPushManifest(ctx, resolver, named, layerDescriptors, api.OCIVersion1_0, extraAnnotations)
|
||||
}
|
||||
return descriptor, err
|
||||
}
|
||||
|
|
@ -137,8 +137,8 @@ func push(ctx context.Context, resolver remotes.Resolver, ref reference.Named, d
|
|||
return Push(ctx, resolver, fullRef, descriptor)
|
||||
}
|
||||
|
||||
func createAndPushManifest(ctx context.Context, resolver remotes.Resolver, named reference.Named, layers []v1.Descriptor, ociVersion api.OCIVersion) (v1.Descriptor, error) {
|
||||
descriptor, toPush, err := generateManifest(layers, ociVersion)
|
||||
func createAndPushManifest(ctx context.Context, resolver remotes.Resolver, named reference.Named, layers []v1.Descriptor, ociVersion api.OCIVersion, extraAnnotations map[string]string) (v1.Descriptor, error) {
|
||||
descriptor, toPush, err := generateManifest(layers, ociVersion, extraAnnotations)
|
||||
if err != nil {
|
||||
return v1.Descriptor{}, err
|
||||
}
|
||||
|
|
@ -159,7 +159,7 @@ func isNonAuthClientError(statusCode int) bool {
|
|||
return !slices.Contains(clientAuthStatusCodes, statusCode)
|
||||
}
|
||||
|
||||
func generateManifest(layers []v1.Descriptor, ociCompat api.OCIVersion) (v1.Descriptor, []v1.Descriptor, error) {
|
||||
func generateManifest(layers []v1.Descriptor, ociCompat api.OCIVersion, extraAnnotations map[string]string) (v1.Descriptor, []v1.Descriptor, error) {
|
||||
var toPush []v1.Descriptor
|
||||
var config v1.Descriptor
|
||||
var artifactType string
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue