diff --git a/cmd/mistry/main.go b/cmd/mistry/main.go index 3e9cca6..3d15183 100644 --- a/cmd/mistry/main.go +++ b/cmd/mistry/main.go @@ -287,7 +287,7 @@ EXAMPLES: fmt.Printf("%s\n", body) } - if bi.ExitCode != 0 { + if bi.ExitCode != types.ExitSuccess { if bi.ContainerStderr != "" { fmt.Fprintln(os.Stderr, "Container error logs:\n", bi.ContainerStderr) } else { diff --git a/cmd/mistryd/testdata/projects/failed-build-link/Dockerfile b/cmd/mistryd/testdata/projects/failed-build-link/Dockerfile new file mode 100644 index 0000000..88c7eef --- /dev/null +++ b/cmd/mistryd/testdata/projects/failed-build-link/Dockerfile @@ -0,0 +1,8 @@ +FROM debian:stretch + +COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh +RUN chmod +x /usr/local/bin/docker-entrypoint.sh + +WORKDIR /data + +ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] diff --git a/cmd/mistryd/testdata/projects/failed-build-link/docker-entrypoint.sh b/cmd/mistryd/testdata/projects/failed-build-link/docker-entrypoint.sh new file mode 100644 index 0000000..2b1da33 --- /dev/null +++ b/cmd/mistryd/testdata/projects/failed-build-link/docker-entrypoint.sh @@ -0,0 +1,2 @@ +#!/bin/bash +exit `cat params/_exitcode` diff --git a/cmd/mistryd/worker.go b/cmd/mistryd/worker.go index cabbcd0..9d7b1b7 100644 --- a/cmd/mistryd/worker.go +++ b/cmd/mistryd/worker.go @@ -131,14 +131,12 @@ func (s *Server) Work(ctx context.Context, j *Job) (buildInfo *types.BuildInfo, } } - // if the build was successful, symlink it to the 'latest' - // path - if err == nil { + // if build was successful, point 'latest' link to it + if err == nil && j.BuildInfo.ExitCode == types.ExitSuccess { // eliminate concurrent filesystem operations since // they could result in a corrupted state (eg. if // jobs of the same project simultaneously finish // successfully) - s.pq.Lock(j.Project) defer s.pq.Unlock(j.Project) diff --git a/cmd/mistryd/worker_test.go b/cmd/mistryd/worker_test.go index 0ba8465..6c1df8f 100644 --- a/cmd/mistryd/worker_test.go +++ b/cmd/mistryd/worker_test.go @@ -68,3 +68,41 @@ func TestFailedPendingBuildCleanup(t *testing.T) { } } } + +// regression test for incremental building bug +func TestBuildCacheWhenFailed(t *testing.T) { + group := "ppp" + + // a successful build - it'll be symlinked + _, err := postJob( + types.JobRequest{Project: "failed-build-link", + Params: types.Params{"_exitcode": "0"}, + Group: group}) + if err != nil { + t.Fatal(err) + } + + // a failed build - it should NOT be symlinked + _, err = postJob( + types.JobRequest{Project: "failed-build-link", + Params: types.Params{"_exitcode": "1", "foo": "bar"}, + Group: group}) + if err != nil { + t.Fatal(err) + } + + // repeat the previous failed build - it + // SHOULD be incremental + buildInfo, err := postJob( + types.JobRequest{Project: "failed-build-link", + Params: types.Params{"_exitcode": "1", "foo": "bar"}, + Group: group}) + if err != nil { + t.Fatal(err) + } + + if !buildInfo.Incremental { + t.Fatal("build should be incremental, but it isn't") + } + +} diff --git a/pkg/types/build_info.go b/pkg/types/build_info.go index 83c9675..6fe656c 100644 --- a/pkg/types/build_info.go +++ b/pkg/types/build_info.go @@ -8,6 +8,9 @@ import ( // before even running the container const ContainerFailureExitCode = -999 +// ExitSuccess indicates that the build was successful. +const ExitSuccess = 0 + // BuildInfo contains various information regarding the outcome of a // particular build. type BuildInfo struct {