Skip to content

Commit 66dfa7d

Browse files
committed
block the publication of an OCI artifact if one or more services contain only a build section
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
1 parent 876ecc4 commit 66dfa7d

File tree

4 files changed

+54
-0
lines changed

4 files changed

+54
-0
lines changed

pkg/compose/publish.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package compose
1818

1919
import (
2020
"context"
21+
"errors"
2122
"fmt"
2223
"os"
2324

@@ -136,6 +137,9 @@ func (s *composeService) generateImageDigestsOverride(ctx context.Context, proje
136137
}
137138

138139
func (s *composeService) preChecks(project *types.Project, options api.PublishOptions) (bool, error) {
140+
if ok, err := s.checkOnlyBuildSection(project); !ok {
141+
return false, err
142+
}
139143
envVariables, err := s.checkEnvironmentVariables(project, options)
140144
if err != nil {
141145
return false, err
@@ -214,3 +218,20 @@ func envFileLayers(project *types.Project) []ocipush.Pushable {
214218
}
215219
return layers
216220
}
221+
222+
func (s *composeService) checkOnlyBuildSection(project *types.Project) (bool, error) {
223+
errorList := []string{}
224+
for _, service := range project.Services {
225+
if service.Image == "" && service.Build != nil {
226+
errorList = append(errorList, service.Name)
227+
}
228+
}
229+
if len(errorList) > 0 {
230+
errMsg := "your Compose stack cannot be published as it only contains a build section for service(s):\n"
231+
for _, serviceInError := range errorList {
232+
errMsg += fmt.Sprintf("- %q\n", serviceInError)
233+
}
234+
return false, errors.New(errMsg)
235+
}
236+
return true, nil
237+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Copyright 2020 Docker Compose CLI authors
2+
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
FROM alpine:latest
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
services:
2+
serviceA:
3+
build:
4+
context: .
5+
dockerfile: Dockerfile
6+
serviceB:
7+
build:
8+
context: .
9+
dockerfile: Dockerfile

pkg/e2e/publish_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,13 @@ FOO=bar`), res.Combined())
107107
assert.Assert(t, strings.Contains(res.Combined(), `BAR=baz`), res.Combined())
108108
assert.Assert(t, strings.Contains(res.Combined(), `QUIX=`), res.Combined())
109109
})
110+
111+
t.Run("refuse to publish with build section only", func(t *testing.T) {
112+
res := c.RunDockerComposeCmdNoCheck(t, "-f", "./fixtures/publish/compose-build-only.yml",
113+
"-p", projectName, "alpha", "publish", "test/test", "--with-env", "-y", "--dry-run")
114+
res.Assert(t, icmd.Expected{ExitCode: 1})
115+
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())
116+
assert.Assert(t, strings.Contains(res.Combined(), "serviceA"), res.Combined())
117+
assert.Assert(t, strings.Contains(res.Combined(), "serviceB"), res.Combined())
118+
})
110119
}

0 commit comments

Comments
 (0)