Browse Source

block the publication of an OCI artifact if one or more services contain only a build section

Signed-off-by: Guillaume Lours <[email protected]>
Guillaume Lours 9 months ago
parent
commit
66dfa7d181

+ 21 - 0
pkg/compose/publish.go

@@ -18,6 +18,7 @@ package compose
 
 import (
 	"context"
+	"errors"
 	"fmt"
 	"os"
 
@@ -136,6 +137,9 @@ func (s *composeService) generateImageDigestsOverride(ctx context.Context, proje
 }
 
 func (s *composeService) preChecks(project *types.Project, options api.PublishOptions) (bool, error) {
+	if ok, err := s.checkOnlyBuildSection(project); !ok {
+		return false, err
+	}
 	envVariables, err := s.checkEnvironmentVariables(project, options)
 	if err != nil {
 		return false, err
@@ -214,3 +218,20 @@ func envFileLayers(project *types.Project) []ocipush.Pushable {
 	}
 	return layers
 }
+
+func (s *composeService) checkOnlyBuildSection(project *types.Project) (bool, error) {
+	errorList := []string{}
+	for _, service := range project.Services {
+		if service.Image == "" && service.Build != nil {
+			errorList = append(errorList, service.Name)
+		}
+	}
+	if len(errorList) > 0 {
+		errMsg := "your Compose stack cannot be published as it only contains a build section for service(s):\n"
+		for _, serviceInError := range errorList {
+			errMsg += fmt.Sprintf("- %q\n", serviceInError)
+		}
+		return false, errors.New(errMsg)
+	}
+	return true, nil
+}

+ 15 - 0
pkg/e2e/fixtures/publish/Dockerfile

@@ -0,0 +1,15 @@
+#   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.
+
+FROM alpine:latest

+ 9 - 0
pkg/e2e/fixtures/publish/compose-build-only.yml

@@ -0,0 +1,9 @@
+services:
+  serviceA:
+    build:
+      context: .
+      dockerfile: Dockerfile
+  serviceB:
+    build:
+      context: .
+      dockerfile: Dockerfile

+ 9 - 0
pkg/e2e/publish_test.go

@@ -107,4 +107,13 @@ FOO=bar`), res.Combined())
 		assert.Assert(t, strings.Contains(res.Combined(), `BAR=baz`), res.Combined())
 		assert.Assert(t, strings.Contains(res.Combined(), `QUIX=`), res.Combined())
 	})
+
+	t.Run("refuse to publish with build section only", func(t *testing.T) {
+		res := c.RunDockerComposeCmdNoCheck(t, "-f", "./fixtures/publish/compose-build-only.yml",
+			"-p", projectName, "alpha", "publish", "test/test", "--with-env", "-y", "--dry-run")
+		res.Assert(t, icmd.Expected{ExitCode: 1})
+		assert.Assert(t, strings.Contains(res.Combined(), "your Compose stack cannot be published as it only contains a build section for service(s):"), res.Combined())
+		assert.Assert(t, strings.Contains(res.Combined(), "serviceA"), res.Combined())
+		assert.Assert(t, strings.Contains(res.Combined(), "serviceB"), res.Combined())
+	})
 }