Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: validate ko's main path #4429

Merged
merged 3 commits into from Nov 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
23 changes: 22 additions & 1 deletion internal/pipe/ko/ko.go
Expand Up @@ -8,6 +8,7 @@
"fmt"
"io"
"path/filepath"
"regexp"
"strconv"
"strings"
"sync"
Expand Down Expand Up @@ -48,7 +49,8 @@
azureKeychain,
)

errNoRepository = errors.New("ko: missing repository: please set either the repository field or a $KO_DOCKER_REPO environment variable")
errNoRepository = errors.New("ko: missing repository: please set either the repository field or a $KO_DOCKER_REPO environment variable")
errInvalidMainPath = errors.New("ko: invalid Main path: ko.main (or build.main if ko.main is not set) should be a relative path.")

Check warning on line 53 in internal/pipe/ko/ko.go

View workflow job for this annotation

GitHub Actions / lint

error-strings: error strings should not be capitalized or end with punctuation or a newline (revive)
)

// Pipe that build OCI compliant images with ko.
Expand Down Expand Up @@ -93,6 +95,10 @@
ko.Main = build.Main
}

if err := validateMainPath(ko.Main); err != nil {
return err
}

if ko.WorkingDir == "" {
ko.WorkingDir = build.Dir
}
Expand Down Expand Up @@ -420,3 +426,18 @@
}
return &v1.Time{Time: time.Unix(seconds, 0)}, nil
}

func validateMainPath(path string) error {
// if the path is empty, it's probably fine as ko will use the default value
if path == "" {
return nil
}
if matched, _ := regexp.MatchString(`^\.?(\.\/[^\/]?.*)?$`, path); !matched {
return errInvalidMainPath
}
// paths sure can have dots in them, but if the path ends in .go, it's propably a file that one misundertood as a valid value
if strings.HasSuffix(path, ".go") {
return errInvalidMainPath
}
return nil
}
52 changes: 52 additions & 0 deletions internal/pipe/ko/ko_test.go
Expand Up @@ -340,6 +340,58 @@ func TestPublishPipeSuccess(t *testing.T) {
}
}

func TestKoValidateMainPathIssue4382(t *testing.T) {
// testing the validation of the main path directly to cover many cases
require.NoError(t, validateMainPath(""))
require.NoError(t, validateMainPath("."))
require.NoError(t, validateMainPath("./..."))
require.NoError(t, validateMainPath("./app"))
require.NoError(t, validateMainPath("../../../..."))
require.NoError(t, validateMainPath("../../app/"))
require.NoError(t, validateMainPath("./testdata/app/main"))
require.NoError(t, validateMainPath("./testdata/app/folder.with.dots"))

require.ErrorIs(t, validateMainPath("app/"), errInvalidMainPath)
require.ErrorIs(t, validateMainPath("/src/"), errInvalidMainPath)
require.ErrorIs(t, validateMainPath("/src/app"), errInvalidMainPath)
require.ErrorIs(t, validateMainPath("./testdata/app/main.go"), errInvalidMainPath)

// testing with real context
ctxOk := testctx.NewWithCfg(config.Project{
Builds: []config.Build{
{
ID: "foo",
Main: "./...",
},
},
Kos: []config.Ko{
{
ID: "default",
Build: "foo",
Repository: "fakerepo",
},
},
})
require.NoError(t, Pipe{}.Default(ctxOk))

ctxWithInvalidMainPath := testctx.NewWithCfg(config.Project{
Builds: []config.Build{
{
ID: "foo",
Main: "/some/non/relative/path",
},
},
Kos: []config.Ko{
{
ID: "default",
Build: "foo",
Repository: "fakerepo",
},
},
})
require.ErrorIs(t, Pipe{}.Default(ctxWithInvalidMainPath), errInvalidMainPath)
}

func TestPublishPipeError(t *testing.T) {
makeCtx := func() *context.Context {
return testctx.NewWithCfg(config.Project{
Expand Down
1 change: 1 addition & 0 deletions www/docs/customization/ko.md
Expand Up @@ -25,6 +25,7 @@ kos:
build: build-id

# Main path to build.
# It must be a relative path
#
# Default: build.main
main: ./cmd/...
Expand Down