diff --git a/.github/workflows/pr-go-workspace-check.yml b/.github/workflows/pr-go-workspace-check.yml index 699f211e1e9..bc5385ef0e0 100644 --- a/.github/workflows/pr-go-workspace-check.yml +++ b/.github/workflows/pr-go-workspace-check.yml @@ -30,4 +30,6 @@ jobs: echo "Please run 'make update-workspace' and commit the changes." echo "If there is a change in enterprise dependencies, please update pkg/extensions/main.go." exit 1 - fi \ No newline at end of file + fi + - name: Ensure Dockerfile contains submodule COPY commands + run: ./scripts/go-workspace/validate-dockerfile.sh \ No newline at end of file diff --git a/scripts/go-workspace/main.go b/scripts/go-workspace/main.go index d25ab44214f..149b117952d 100644 --- a/scripts/go-workspace/main.go +++ b/scripts/go-workspace/main.go @@ -19,6 +19,8 @@ func main() { switch os.Args[1] { case "list-submodules": err = listSubmodules() + case "validate-dockerfile": + err = validateDockerfile() default: printUsage() } @@ -40,7 +42,9 @@ func listSubmodules() error { delimiter := fs.String("delimiter", "\n", "Delimiter to use when printing paths") skip := fs.String("skip", "", "Skip submodules with this comment tag") help := fs.Bool("help", false, "Print help message") - fs.Parse(os.Args[2:]) + if err := fs.Parse(os.Args[2:]); err != nil { + return err + } if *help { fs.Usage() @@ -60,6 +64,41 @@ func listSubmodules() error { return nil } +func validateDockerfile() error { + fs := flag.NewFlagSet("validate-dockerfile", flag.ExitOnError) + workPath := fs.String("path", "go.work", "Path to go.work") + dockerfilePath := fs.String("dockerfile-path", "Dockerfile", "Path to Dockerfile") + skip := fs.String("skip", "", "Skip submodules with this comment tag") + if err := fs.Parse(os.Args[2:]); err != nil { + return err + } + + dockerFileRaw, err := os.ReadFile(*dockerfilePath) + if err != nil { + return err + } + dockerFile := string(dockerFileRaw) + + workfile, err := parseGoWork(*workPath) + if err != nil { + return err + } + + paths := getSubmodulePaths(workfile, *skip) + for _, p := range paths { + path := strings.TrimPrefix(p, "./") + if path == "" || path == "." { + continue + } + if !strings.Contains(dockerFile, path) { + return fmt.Errorf("the Dockerfile is missing `COPY %s/go.* %s` for the related module. Please add it and commit the change.", path, path) + } + } + + fmt.Println("All submodules are included in the Dockerfile.") + return nil +} + func getSubmodulePaths(wf *modfile.WorkFile, skip string) []string { var paths []string for _, d := range wf.Use { diff --git a/scripts/go-workspace/validate-dockerfile.sh b/scripts/go-workspace/validate-dockerfile.sh new file mode 100755 index 00000000000..17ee08b6a51 --- /dev/null +++ b/scripts/go-workspace/validate-dockerfile.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +set -o errexit +set -o nounset +set -o pipefail + +REPO_ROOT=$(dirname "${BASH_SOURCE[0]}")/../.. +go run scripts/go-workspace/main.go validate-dockerfile --path "${REPO_ROOT}/go.work" --dockerfile-path "${REPO_ROOT}/Dockerfile" \ No newline at end of file