From f990b3b9fe9c80dfffa6c132bf58fc39ed1707b8 Mon Sep 17 00:00:00 2001 From: smorihira Date: Wed, 4 Sep 2024 14:43:31 +0900 Subject: [PATCH] chore: write a template of actions/gen/main.go --- hack/actions/gen/main.go | 367 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 367 insertions(+) diff --git a/hack/actions/gen/main.go b/hack/actions/gen/main.go index e69de29bb2..6ac592b0c0 100644 --- a/hack/actions/gen/main.go +++ b/hack/actions/gen/main.go @@ -0,0 +1,367 @@ +package main + +import ( + "context" + "errors" + "io/fs" + "os" + "os/signal" + "syscall" + "time" + + "github.com/vdaas/vald/internal/file" + "github.com/vdaas/vald/internal/log" + "github.com/vdaas/vald/internal/safety" + "github.com/vdaas/vald/internal/sync/errgroup" +) + +type ( + name string + cron string + uses string + target string + secrets string + + branches []string + paths []string + platforms []string + + schedule struct { + cron cron + } + + push struct { + branches branches + } + + pull_request struct { + paths paths + } + + pull_request_target struct { + paths paths + } + + on struct { + schedule schedule + push push + pull_request pull_request + pull_request_target pull_request_target + } + + with struct { + target target + platforms platforms + } + + build struct { + uses uses + with with + secrets secrets + } + + jobs struct { + build build + } + + workflow struct { + name name + on on + jobs jobs + } +) +type Data struct { + AliasImage bool + ConfigExists bool + Year int + ContainerType ContainerType + AppName string + BinDir string + BuildUser string + BuilderImage string + BuilderTag string + BuildStageName string + Maintainer string + PackageDir string + RootDir string + RuntimeImage string + RuntimeTag string + RuntimeUser string + Arguments map[string]string + Environments map[string]string + Entrypoints []string + EnvironmentsSlice []string + ExtraCopies []string + ExtraImages []string + ExtraPackages []string + Preprocess []string + RunCommands []string + RunMounts []string + StageFiles []string + // TODO: 以下追加分? + ComponentName string +} + +type ContainerType int + +const ( + Go ContainerType = iota + Rust + DevContainer + HelmOperator + CIContainer + Other +) + +// TODO: 必要な定数はここに追加 +const ( + organization = "vdaas" + repository = "vald" + defaultBinaryDir = "/usr/bin" + defaultBuilderImage = "ghcr.io/vdaas/vald/vald-buildbase" + defaultBuilderTag = "nightly" + defaultLanguage = "en_US.UTF-8" + defaultMaintainer = organization + ".org " + repository + " team <" + repository + "@" + organization + ".org>" + defaultRuntimeImage = "gcr.io/distroless/static" + defaultRuntimeTag = "nonroot" + defaultRuntimeUser = "nonroot:nonroot" + defaultBuildUser = "root:root" + defaultBuildStageName = "builder" + maintainerKey = "MAINTAINER" + minimumArgumentLength = 2 + ubuntuVersion = "22.04" + + goWorkdir = "${GOPATH}/src/github.com" + rustWorkdir = "${HOME}/rust/src/github.com" + + agentInernalPackage = "pkg/agent/internal" + + ngtPreprocess = "make ngt/install" + faissPreprocess = "make faiss/install" + + helmOperatorRootdir = "/opt/helm" + helmOperatorWatchFile = helmOperatorRootdir + "/watches.yaml" + helmOperatorChartsDir = helmOperatorRootdir + "/charts" +) + +func (c ContainerType) String() string { + return containerTypeName[c] +} + +// TODO: 必要な変数はここに追加 +var ( + containerTypeName = map[ContainerType]string{ + Go: "Go", + Rust: "Rust", + DevContainer: "DevContainer", + HelmOperator: "HelmOperator", + CIContainer: "CIContainer", + Other: "Other", + } + + defaultEnvironments = map[string]string{ + "DEBIAN_FRONTEND": "noninteractive", + "HOME": "/root", + "USER": "root", + "INITRD": "No", + "LANG": defaultLanguage, + "LANGUAGE": defaultLanguage, + "LC_ALL": defaultLanguage, + "ORG": organization, + "TZ": "Etc/UTC", + "PATH": "${PATH}:/usr/local/bin", + "REPO": repository, + } + goDefaultEnvironments = map[string]string{ + "GOROOT": "/opt/go", + "GOPATH": "/go", + "GO111MODULE": "on", + "PATH": "${PATH}:${GOROOT}/bin:${GOPATH}/bin:/usr/local/bin", + } + rustDefaultEnvironments = map[string]string{ + "RUST_HOME": "/usr/loacl/lib/rust", + "RUSTUP_HOME": "${RUST_HOME}/rustup", + "CARGO_HOME": "${RUST_HOME}/cargo", + "PATH": "${PATH}:${RUSTUP_HOME}/bin:${CARGO_HOME}/bin:/usr/local/bin", + } + clangDefaultEnvironments = map[string]string{ + "CC": "gcc", + "CXX": "g++", + } + goInstallCommands = []string{ + "make GOPATH=\"${GOPATH}\" GOROOT=\"${GOROOT}\" GO_VERSION=\"${GO_VERSION}\" go/install", + "make GOPATH=\"${GOPATH}\" GOROOT=\"${GOROOT}\" GO_VERSION=\"${GO_VERSION}\" go/download", + } + rustInstallCommands = []string{ + "make RUST_VERSION=\"${RUST_VERSION}\" rust/install", + } + goBuildCommands = []string{ + "make GOARCH=\"${TARGETARCH}\" GOOS=\"${TARGETOS}\" REPO=\"${ORG}\" NAME=\"${REPO}\" cmd/${PKG}/${APP_NAME}", + "mv \"cmd/${PKG}/${APP_NAME}\" \"{{$.BinDir}}/${APP_NAME}\"", + } + rustBuildCommands = []string{ + "make rust/target/release/${APP_NAME}", + "mv \"rust/target/release/${APP_NAME}\" \"{{$.BinDir}}/${APP_NAME}\"", + "rm -rf rust/target", + } + + defaultMounts = []string{ + "--mount=type=bind,target=.,rw", + "--mount=type=tmpfs,target=/tmp", + "--mount=type=cache,target=/var/lib/apt,sharing=locked", + "--mount=type=cache,target=/var/cache/apt,sharing=locked", + } + + goDefaultMounts = []string{ + "--mount=type=cache,target=\"${GOPATH}/pkg\",id=\"go-build-${TARGETARCH}\"", + "--mount=type=cache,target=\"${HOME}/.cache/go-build\",id=\"go-build-${TARGETARCH}\"", + } + + clangBuildDeps = []string{ + "cmake", + "gcc", + "g++", + "unzip", + "libssl-dev", + } + ngtBuildDeps = []string{ + "liblapack-dev", + "libomp-dev", + "libopenblas-dev", + } + faissBuildDeps = []string{ + "gfortran", + } + devContainerDeps = []string{ + "gawk", + "gnupg2", + "graphviz", + "jq", + "libhdf5-dev", + "libaec-dev", + "sed", + "zip", + } + + ciContainerPreprocess = []string{ + "make GOARCH=${TARGETARCH} GOOS=${TARGETOS} deps GO_CLEAN_DEPS=false", + "make GOARCH=${TARGETARCH} GOOS=${TARGETOS} golangci-lint/install", + "make GOARCH=${TARGETARCH} GOOS=${TARGETOS} gotestfmt/install", + "make cmake/install", + "make buf/install", + "make hdf5/install", + "make helm-docs/install", + "make helm/install", + "make k3d/install", + "make k9s/install", + "make kind/install", + "make kubectl/install", + "make kubelinter/install", + "make reviewdog/install", + "make tparse/install", + "make valdcli/install", + "make yq/install", + "make minikube/install", + "make stern/install", + "make telepresence/install", + } + + devContainerPreprocess = []string{ + "curl -fsSL https://deb.nodesource.com/setup_current.x | bash -", + "apt-get clean", + "apt-get update -y", + "apt-get upgrade -y", + "apt-get install -y --no-install-recommends --fix-missing nodejs", + "npm install -g npm@latest", + "apt-get clean", + "apt-get autoclean -y", + "apt-get autoremove -y", + "make delve/install", + "make gomodifytags/install", + "make gopls/install", + "make gotests/install", + "make impl/install", + "make staticcheck/install", + } +) + +func main() { + // この辺の処理は共通? + log.Init() + if len(os.Args) < minimumArgumentLength { + // skipcq: RVV-A0003 + log.Fatal(errors.New("invalid argument")) + } + + ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, + syscall.SIGQUIT, + syscall.SIGHUP, + syscall.SIGALRM, + syscall.SIGKILL, + syscall.SIGTERM) + defer cancel() + log.Debug(tmpl) + + maintainer := os.Getenv(maintainerKey) + if maintainer == "" { + maintainer = defaultMaintainer + } + year := time.Now().Year() + eg, egctx := errgroup.New(ctx) + for n, d := range map[string]Data{ + // TODO: mapを入れる + } { + name := n + data := d + + eg.Go(safety.RecoverFunc(func() error { + data.Maintainer = maintainer + data.Year = year + if data.BinDir == "" { + data.BinDir = defaultBinaryDir + } + if data.RuntimeImage == "" { + data.RuntimeImage = defaultRuntimeImage + } + if data.RuntimeTag == "" { + data.RuntimeTag = defaultRuntimeTag + } + if data.BuilderImage == "" { + data.BuilderImage = defaultBuilderImage + } + if data.BuilderTag == "" { + data.BuilderTag = defaultBuilderTag + } + if data.RuntimeUser == "" { + data.RuntimeUser = defaultRuntimeUser + } + if data.BuildUser == "" { + data.BuildUser = defaultBuildUser + } + if data.BuildStageName == "" { + data.BuildStageName = defaultBuildStageName + } + if data.Environments != nil { + data.Environments = appendM(data.Environments, defaultEnvironments) + } else { + data.Environments = make(map[string]string, len(defaultEnvironments)) + data.Environments = appendM(data.Environments, defaultEnvironments) + } + + // ContainerTypeごとの処理 (workflow生成でも重要そう) + + // ↑ここまでdataの処理 (workflowの生成でもほとんど共通?) + + // ↓ここからファイルの生成 + // buf := bytes.NewBuffer(make([]byte, 0, len(tmpl))) + log.Infof("Generating %s's workflow", name) + // workflow.Execute(buf, data) + tpl := buf.String() + buf.Reset() + // template.Must(template.New("workflow").Parse(tpl)).Execute(buf, data) + file.OverWriteFile(egctx, file.Join(os.Args[1], "actions", data.PackageDir, "TODO: ファイル名"), buf, fs.ModePerm) + return nil + })) + } + +}