diff --git a/internal/infra/run.go b/internal/infra/run.go index 932b83a..902094f 100644 --- a/internal/infra/run.go +++ b/internal/infra/run.go @@ -13,6 +13,7 @@ import ( "net/http" "os" "os/signal" + "regexp" "strings" "syscall" "time" @@ -62,7 +63,23 @@ type RunParams struct { InputRaw []byte } +var gitShaRegex = regexp.MustCompile(`^[0-9a-f]{40}$`) + +func (p *RunParams) Validate() error { + if p.Job == nil { + return fmt.Errorf("job is required") + } + if p.Job.Source.Commit != nil && *p.Job.Source.Commit != "" && !gitShaRegex.MatchString(*p.Job.Source.Commit) { + return fmt.Errorf("commit must be a SHA, or not provided") + } + return nil +} + func Run(params RunParams) error { + if err := params.Validate(); err != nil { + return err + } + var ctx context.Context var cancel func() if params.Timeout > 0 { diff --git a/testdata/invalid-commit.yml b/testdata/invalid-commit.yml new file mode 100644 index 0000000..7e6627b --- /dev/null +++ b/testdata/invalid-commit.yml @@ -0,0 +1,10 @@ +job: + package-manager: go_modules + allowed-updates: + - dependency-type: direct + update-type: all + source: + provider: github + repo: rsc/quote + directory: / + commit: unknown diff --git a/testdata/valid-commit.yml b/testdata/valid-commit.yml new file mode 100644 index 0000000..78bbd17 --- /dev/null +++ b/testdata/valid-commit.yml @@ -0,0 +1,10 @@ +job: + package-manager: go_modules + allowed-updates: + - dependency-type: direct + update-type: all + source: + provider: github + repo: rsc/quote + directory: / + commit: 5d9f230bcfbae514bb6c2215694c2ce7273fc604 diff --git a/tests/integration_test.go b/tests/integration_test.go new file mode 100644 index 0000000..b638cde --- /dev/null +++ b/tests/integration_test.go @@ -0,0 +1,49 @@ +package tests + +import ( + "os" + "os/exec" + "path" + "path/filepath" + "runtime" + "strings" + "testing" +) + +func TestIntegration(t *testing.T) { + // build the binary for the rest of the tests + _, filename, _, _ := runtime.Caller(0) + testPath := filepath.Dir(filename) + cliMain := path.Join(testPath, "../cmd/dependabot/dependabot.go") + + if data, err := exec.Command("go", "build", cliMain).CombinedOutput(); err != nil { + t.Fatal("Failed to build the binary: ", string(data)) + } + defer func() { + _ = os.Remove("dependabot") + }() + + // Helper to run dependabot in the right directory + dependabot := func(args ...string) (string, error) { + cmd := exec.Command("./dependabot", args...) + cmd.Dir = testPath + output, err := cmd.CombinedOutput() + return string(output), err + } + + t.Run("works with valid commits", func(t *testing.T) { + if output, err := dependabot("update", "-f", "../testdata/valid-commit.yml"); err != nil { + t.Fatal("Expected no error, but got: ", output) + } + }) + + t.Run("rejects invalid commits", func(t *testing.T) { + output, err := dependabot("update", "-f", "../testdata/invalid-commit.yml") + if err == nil { + t.Fatal("Expected an error, but got none") + } + if !strings.Contains(output, "commit must be a SHA, or not provided") { + t.Fatalf("Expected error message to mention bad commit, but got: \n%s", output) + } + }) +}