diff --git a/cicd-mcp-server/REFERENCE.md b/cicd-mcp-server/REFERENCE.md index f753505..45d8c42 100644 --- a/cicd-mcp-server/REFERENCE.md +++ b/cicd-mcp-server/REFERENCE.md @@ -78,6 +78,21 @@ Creates a new Cloud Run service or updates an existing one from source. - `port` (integer, optional): The port the container listens on. - `allow_public_access` (boolean, optional): If the service should be public. Default is `false`. +### `deploy_cloudrun_service_no_build` +Creates a new Cloud Run service or updates an existing one from source without a build step, utilizing a Google-managed base image. + +**Arguments:** +- `project_id` (string, required): The Google Cloud project ID. +- `location` (string, required): The Google Cloud location. +- `service_name` (string, required): The name of the Cloud Run service. +- `source` (string, required): The path to the source code to deploy. +- `base_image` (string, required): The runtime base image (e.g., `nodejs24`, `python314`, `osonly24`). +- `command` (string, optional): The command that the container starts up with. +- `args` (array of strings, optional): Arguments to pass to the container command. +- `env_vars` (object with string keys and values, optional): Environment variables to set. +- `port` (integer, optional): The port the container listens on. +- `allow_public_access` (boolean, optional): If the service should be public. Default is `false`. + ## Developer Connect ### `create_git_connection` diff --git a/cicd-mcp-server/cloudrun/client/cloudrunclient.go b/cicd-mcp-server/cloudrun/client/cloudrunclient.go index 09645d1..37e32b7 100644 --- a/cicd-mcp-server/cloudrun/client/cloudrunclient.go +++ b/cicd-mcp-server/cloudrun/client/cloudrunclient.go @@ -18,6 +18,7 @@ import ( "context" "fmt" "os/exec" + "strings" "google.golang.org/api/iterator" @@ -52,6 +53,7 @@ type CloudRunClient interface { UpdateService(ctx context.Context, projectID, location, serviceName, imageURL, revisionName string, port int32, service *cloudrunpb.Service) (*cloudrunpb.Service, error) GetRevision(ctx context.Context, service *cloudrunpb.Service) (*cloudrunpb.Revision, error) DeployFromSource(ctx context.Context, projectID, location, serviceName, source string, port int32, allowPublicAccess bool) error + DeployNoBuild(ctx context.Context, projectID, location, serviceName, source, baseImage, command string, cmdArgs []string, envVars map[string]string, port int32, allowPublicAccess bool) error DeleteService(ctx context.Context, projectID, location, serviceName string) error SetServiceAccess(ctx context.Context, serviceName string, allowPublicAccess bool) error } @@ -202,6 +204,42 @@ func (c *CloudRunClientImpl) DeployFromSource(ctx context.Context, projectID, lo return nil } +// DeployNoBuild deploys a Cloud Run service from source without a build step, using a base image. +func (c *CloudRunClientImpl) DeployNoBuild(ctx context.Context, projectID, location, serviceName, source, baseImage, command string, cmdArgs []string, envVars map[string]string, port int32, allowPublicAccess bool) error { + args := []string{"beta", "run", "deploy", serviceName, "--project", projectID, "--region", location, "--source", source, "--no-build", "--base-image", baseImage, "--format", "json", "--quiet"} + if command != "" { + args = append(args, "--command", command) + } + if len(cmdArgs) > 0 { + argStr := strings.Join(cmdArgs, ",") + args = append(args, fmt.Sprintf("--args=%s", argStr)) + } + if len(envVars) > 0 { + envPairs := make([]string, 0, len(envVars)) + for k, v := range envVars { + envPairs = append(envPairs, fmt.Sprintf("%s=%s", k, v)) + } + envStr := strings.Join(envPairs, ",") + args = append(args, "--set-env-vars", envStr) + } + if port != 0 { + args = append(args, "--port", fmt.Sprintf("%d", port)) + } + if allowPublicAccess { + args = append(args, "--allow-unauthenticated") + } else { + args = append(args, "--no-allow-unauthenticated") + } + + cmd := c.execer.Command("gcloud", args...) + out, err := cmd.CombinedOutput() + if err != nil { + return fmt.Errorf("failed to deploy no-build: %w, output: %s", err, out) + } + return nil +} + + // DeleteService deletes a Cloud Run service. func (c *CloudRunClientImpl) DeleteService(ctx context.Context, projectID, location, serviceName string) error { name := fmt.Sprintf("projects/%s/locations/%s/services/%s", projectID, location, serviceName) diff --git a/cicd-mcp-server/cloudrun/client/mocks/mock_cloudrunclient.go b/cicd-mcp-server/cloudrun/client/mocks/mock_cloudrunclient.go index fdb6cd1..a200a23 100644 --- a/cicd-mcp-server/cloudrun/client/mocks/mock_cloudrunclient.go +++ b/cicd-mcp-server/cloudrun/client/mocks/mock_cloudrunclient.go @@ -28,6 +28,7 @@ type MockCloudRunClient struct { UpdateServiceFunc func(ctx context.Context, projectID, location, serviceName, imageURL, revisionName string, port int32, service *cloudrunpb.Service) (*cloudrunpb.Service, error) GetRevisionFunc func(ctx context.Context, service *cloudrunpb.Service) (*cloudrunpb.Revision, error) DeployFromSourceFunc func(ctx context.Context, projectID, location, serviceName, source string, port int32, allowPublicAccess bool) error + DeployNoBuildFunc func(ctx context.Context, projectID, location, serviceName, source, baseImage, command string, cmdArgs []string, envVars map[string]string, port int32, allowPublicAccess bool) error DeleteServiceFunc func(ctx context.Context, projectID, location, serviceName string) error SetServiceAccessFunc func(ctx context.Context, serviceName string, allowPublicAccess bool) error } @@ -67,6 +68,11 @@ func (m *MockCloudRunClient) DeployFromSource(ctx context.Context, projectID, lo return m.DeployFromSourceFunc(ctx, projectID, location, serviceName, source, port, allowPublicAccess) } +// DeployNoBuild mocks the DeployNoBuild method. +func (m *MockCloudRunClient) DeployNoBuild(ctx context.Context, projectID, location, serviceName, source, baseImage, command string, cmdArgs []string, envVars map[string]string, port int32, allowPublicAccess bool) error { + return m.DeployNoBuildFunc(ctx, projectID, location, serviceName, source, baseImage, command, cmdArgs, envVars, port, allowPublicAccess) +} + func (m *MockCloudRunClient) SetServiceAccess(ctx context.Context, serviceName string, allowPublicAccess bool) error { return m.SetServiceAccessFunc(ctx, serviceName, allowPublicAccess) } diff --git a/cicd-mcp-server/cloudrun/cloudrun.go b/cicd-mcp-server/cloudrun/cloudrun.go index 9c5a4b0..93cb462 100644 --- a/cicd-mcp-server/cloudrun/cloudrun.go +++ b/cicd-mcp-server/cloudrun/cloudrun.go @@ -36,6 +36,7 @@ func (h *Handler) Register(server *mcp.Server) { addListServicesTool(server, h.CrClient) addDeployToCloudRunFromImageTool(server, h.CrClient) addDeployToCloudRunFromSourceTool(server, h.CrClient) + addDeployToCloudRunNoBuildTool(server, h.CrClient) } type ListServicesArgs struct { @@ -134,3 +135,34 @@ func addDeployToCloudRunFromSourceTool(server *mcp.Server, crClient cloudrunclie } mcp.AddTool(server, &mcp.Tool{Name: "deploy_cloudrun_service_from_source", Description: "Creates a new Cloud Run service or updates an existing one from source. This tool may take a couple minutes to finish running."}, deployToCloudRunFromSourceToolFunc) } + +type DeployToCloudRunNoBuildArgs struct { + ProjectID string `json:"project_id" jsonschema:"The Google Cloud project ID."` + Location string `json:"location" jsonschema:"The Google Cloud location."` + ServiceName string `json:"service_name" jsonschema:"The name of the Cloud Run service."` + Source string `json:"source" jsonschema:"The path to the source code to deploy."` + BaseImage string `json:"base_image" jsonschema:"The runtime base image (e.g., nodejs24, python314, osonly24)."` + Command string `json:"command,omitempty" jsonschema:"The command that the container starts up with."` + Args []string `json:"args,omitempty" jsonschema:"Arguments to pass to the container command."` + EnvVars map[string]string `json:"env_vars,omitempty" jsonschema:"Environment variables to set."` + Port int32 `json:"port,omitempty" jsonschema:"The port the container listens on."` + AllowPublicAccess bool `json:"allow_public_access,omitempty" jsonschema:"If the service should be public. Default is false."` +} + +var deployToCloudRunNoBuildToolFunc func(ctx context.Context, req *mcp.CallToolRequest, args DeployToCloudRunNoBuildArgs) (*mcp.CallToolResult, any, error) + +func addDeployToCloudRunNoBuildTool(server *mcp.Server, crClient cloudrunclient.CloudRunClient) { + deployToCloudRunNoBuildToolFunc = func(ctx context.Context, req *mcp.CallToolRequest, args DeployToCloudRunNoBuildArgs) (*mcp.CallToolResult, any, error) { + err := crClient.DeployNoBuild(ctx, args.ProjectID, args.Location, args.ServiceName, args.Source, args.BaseImage, args.Command, args.Args, args.EnvVars, args.Port, args.AllowPublicAccess) + if err != nil { + return &mcp.CallToolResult{}, nil, fmt.Errorf("failed to deploy service: %w", err) + } + service, err := crClient.GetService(ctx, args.ProjectID, args.Location, args.ServiceName) + if err != nil { + return &mcp.CallToolResult{}, nil, fmt.Errorf("failed to get service: %w", err) + } + return &mcp.CallToolResult{}, service, nil + } + mcp.AddTool(server, &mcp.Tool{Name: "deploy_cloudrun_service_no_build", Description: "Creates a new Cloud Run service or updates an existing one from source without a build step, using a pre-configured base image. This tool may take a couple minutes to finish running."}, deployToCloudRunNoBuildToolFunc) +} + diff --git a/cicd-mcp-server/go.mod b/cicd-mcp-server/go.mod index 60e75f1..f74c084 100644 --- a/cicd-mcp-server/go.mod +++ b/cicd-mcp-server/go.mod @@ -19,7 +19,7 @@ require ( github.com/philippgille/chromem-go v0.7.0 github.com/stretchr/testify v1.11.1 google.golang.org/api v0.252.0 - google.golang.org/grpc v1.78.0 + google.golang.org/grpc v1.79.3 google.golang.org/protobuf v1.36.11 ) @@ -117,6 +117,7 @@ require ( github.com/moby/sys/signal v0.7.1 // indirect github.com/moby/sys/user v0.4.0 // indirect github.com/moby/sys/userns v0.1.0 // indirect + github.com/moby/term v0.5.0 // indirect github.com/ncruces/go-strftime v0.1.9 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.1 // indirect @@ -165,7 +166,7 @@ require ( go.opentelemetry.io/otel/sdk v1.43.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.43.0 // indirect go.opentelemetry.io/otel/trace v1.43.0 // indirect - go.opentelemetry.io/proto/otlp v1.7.0 // indirect + go.opentelemetry.io/proto/otlp v1.7.1 // indirect go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.17.0 // indirect @@ -185,8 +186,8 @@ require ( golang.org/x/vuln v1.1.4 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect google.golang.org/genproto v0.0.0-20251020155222-88f65dc88635 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20251029180050-ab9386a59fda // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/cicd-mcp-server/go.sum b/cicd-mcp-server/go.sum index a01c420..6867b35 100644 --- a/cicd-mcp-server/go.sum +++ b/cicd-mcp-server/go.sum @@ -78,8 +78,8 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/xds/go v0.0.0-20251022180443-0feb69152e9f h1:Y8xYupdHxryycyPlc9Y+bSQAYZnetRJ70VMVKm5CKI0= -github.com/cncf/xds/go v0.0.0-20251022180443-0feb69152e9f/go.mod h1:HlzOvOjVBOfTGSRXRyY0OiCS/3J1akRGQQpRO/7zyF4= +github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 h1:6xNmx7iTtyBRev0+D/Tv1FZd4SCg8axKApyNyRsAt/w= +github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5/go.mod h1:KdCmV+x/BuvyMxRnYBlmVaq4OLiKW6iRQfvC62cvdkI= github.com/compose-spec/compose-go/v2 v2.8.1 h1:27O4dzyhiS/UEUKp1zHOHCBWD1WbxGsYGMNNaSejTk4= github.com/compose-spec/compose-go/v2 v2.8.1/go.mod h1:veko/VB7URrg/tKz3vmIAQDaz+CGiXH8vZsW79NmAww= github.com/containerd/cgroups/v3 v3.0.5 h1:44na7Ud+VwyE7LIoJ8JTNQOa549a8543BmzaJHo6Bzo= @@ -151,12 +151,12 @@ github.com/elliotwutingfeng/asciiset v0.0.0-20230602022725-51bbb787efab/go.mod h github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.13.5-0.20251024222203-75eaa193e329 h1:K+fnvUM0VZ7ZFJf0n4L/BRlnsb9pL/GuDG6FqaH+PwM= -github.com/envoyproxy/go-control-plane/envoy v1.35.0 h1:ixjkELDE+ru6idPxcHLj8LBVc2bFP7iBytj353BoHUo= -github.com/envoyproxy/go-control-plane/envoy v1.35.0/go.mod h1:09qwbGVuSWWAyN5t/b3iyVfz5+z8QWGrzkoqm/8SbEs= +github.com/envoyproxy/go-control-plane v0.14.0 h1:hbG2kr4RuFj222B6+7T83thSPqLjwBIfQawTkC++2HA= +github.com/envoyproxy/go-control-plane/envoy v1.36.0 h1:yg/JjO5E7ubRyKX3m07GF3reDNEnfOboJ0QySbH736g= +github.com/envoyproxy/go-control-plane/envoy v1.36.0/go.mod h1:ty89S1YCCVruQAm9OtKeEkQLTb+Lkz0k8v9W0Oxsv98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8= -github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU= +github.com/envoyproxy/protoc-gen-validate v1.3.0 h1:TvGH1wof4H33rezVKWSpqKz5NXWg5VPuZ0uONDT6eb4= +github.com/envoyproxy/protoc-gen-validate v1.3.0/go.mod h1:HvYl7zwPa5mffgyeTUHA9zHIH36nmrm7oCbo4YKoSWA= github.com/erikvarga/go-rpmdb v0.0.0-20250523120114-a15a62cd4593 h1:cIQ/Ziclb/qreqg1nqGEtH4V9UJCTaNSKz9gBRaeZlA= github.com/erikvarga/go-rpmdb v0.0.0-20250523120114-a15a62cd4593/go.mod h1:MiEorPk0IChAoCwpg2FXyqVgbNvOlPWZAYHqqIoDNoY= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= @@ -243,8 +243,8 @@ github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= github.com/googleapis/gax-go/v2 v2.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81vgd/bo= github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90= github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E= github.com/invopop/jsonschema v0.13.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= @@ -293,8 +293,8 @@ github.com/moby/sys/user v0.4.0 h1:jhcMKit7SA80hivmFJcbB1vqmw//wU61Zdui2eQXuMs= github.com/moby/sys/user v0.4.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs= github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g= github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28= -github.com/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA= -github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= +github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= +github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modelcontextprotocol/go-sdk v1.4.1 h1:M4x9GyIPj+HoIlHNGpK2hq5o3BFhC+78PkEaldQRphc= github.com/modelcontextprotocol/go-sdk v1.4.1/go.mod h1:Bo/mS87hPQqHSRkMv4dQq1XCu6zv4INdXnFZabkNU6s= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= @@ -441,8 +441,8 @@ go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfC go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A= go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A= go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0= -go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os= -go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo= +go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= +go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= @@ -565,17 +565,17 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98 google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20251020155222-88f65dc88635 h1:I5FLgnlmGA5voD3BZp9Rc17FGiius/DlMB3WsJ1C4Xw= google.golang.org/genproto v0.0.0-20251020155222-88f65dc88635/go.mod h1:1Ic78BnpzY8OaTCmzxJDP4qC9INZPbGZl+54RKjtyeI= -google.golang.org/genproto/googleapis/api v0.0.0-20251029180050-ab9386a59fda h1:+2XxjfsAu6vqFxwGBRcHiMaDCuZiqXGDUDVWVtrFAnE= -google.golang.org/genproto/googleapis/api v0.0.0-20251029180050-ab9386a59fda/go.mod h1:fDMmzKV90WSg1NbozdqrE64fkuTv6mlq2zxo9ad+3yo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda h1:i/Q+bfisr7gq6feoJnS/DlpdwEL4ihp41fvRiM3Ork0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc= -google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/local-kb-index-builder/go.mod b/local-kb-index-builder/go.mod index 8b0ce1b..caa175f 100644 --- a/local-kb-index-builder/go.mod +++ b/local-kb-index-builder/go.mod @@ -20,7 +20,8 @@ require ( github.com/andybalholm/cascadia v1.3.3 // indirect github.com/cloudflare/circl v1.6.3 // indirect github.com/cyphar/filepath-securejoin v0.6.0 // indirect - github.com/dlclark/regexp2 v1.10.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/dlclark/regexp2 v1.11.0 // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/go-billy/v5 v5.8.0 // indirect @@ -32,6 +33,7 @@ require ( github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/pjbgf/sha1cd v0.3.2 // indirect github.com/pkoukk/tiktoken-go v0.1.6 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/skeema/knownhosts v1.3.1 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect @@ -40,16 +42,19 @@ require ( gitlab.com/golang-commonmark/markdown v0.0.0-20211110145824-bf3e522c626a // indirect gitlab.com/golang-commonmark/mdurl v0.0.0-20191124015652-932350d1cb84 // indirect gitlab.com/golang-commonmark/puny v0.0.0-20191124015043-9f83538fa04f // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect + go.opentelemetry.io/otel v1.43.0 // indirect + go.opentelemetry.io/otel/metric v1.43.0 // indirect + go.opentelemetry.io/otel/trace v1.43.0 // indirect golang.org/x/crypto v0.47.0 // indirect + golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 // indirect golang.org/x/net v0.49.0 // indirect - golang.org/x/sys v0.40.0 // indirect + golang.org/x/sys v0.42.0 // indirect golang.org/x/text v0.33.0 // indirect google.golang.org/grpc v1.79.3 // indirect google.golang.org/protobuf v1.36.11 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect + sigs.k8s.io/yaml v1.4.0 // indirect ) replace cicd/lib/bm25 => ../lib/bm25 diff --git a/local-kb-index-builder/go.sum b/local-kb-index-builder/go.sum index 931ff9e..d8e6d99 100644 --- a/local-kb-index-builder/go.sum +++ b/local-kb-index-builder/go.sum @@ -28,10 +28,9 @@ github.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJ github.com/cyphar/filepath-securejoin v0.6.0 h1:BtGB77njd6SVO6VztOHfPxKitJvd/VPT+OFBFMOi1Is= github.com/cyphar/filepath-securejoin v0.6.0/go.mod h1:A8hd4EnAeyujCJRrICiOWqjS1AX0a9kM5XL+NwKoYSc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0= -github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI= github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o= github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= @@ -87,8 +86,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkoukk/tiktoken-go v0.1.6 h1:JF0TlJzhTbrI30wCvFuiw6FzP2+/bR+FIxUdgEAcUsw= github.com/pkoukk/tiktoken-go v0.1.6/go.mod h1:9NiV+i9mJKGj1rYOT+njbv+ZwA/zJxYdewGl6qVatpg= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= @@ -129,14 +128,10 @@ gitlab.com/opennota/wd v0.0.0-20180912061657-c5d65f63c638 h1:uPZaMiz6Sz0PZs3IZJW gitlab.com/opennota/wd v0.0.0-20180912061657-c5d65f63c638/go.mod h1:EGRJaqe2eO9XGmFtQCvV3Lm9NLico3UhFwUpCG/+mVU= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18= +go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I= +go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM= +go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= @@ -147,8 +142,7 @@ golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8= golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= @@ -192,8 +186,7 @@ golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -245,5 +238,4 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= -sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= +sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= diff --git a/skills/google-cicd-deploy/SKILL.md b/skills/google-cicd-deploy/SKILL.md index 15eaebd..5ea7a88 100644 --- a/skills/google-cicd-deploy/SKILL.md +++ b/skills/google-cicd-deploy/SKILL.md @@ -28,11 +28,12 @@ You are a comprehensive Google Cloud CI/CD Assistant. Your primary function is t ### **Workflow Selection:** Based on the analysis, elect the appropriate workflow: * If the type is a static application, follow **Workflow A: Google Cloud Storage**. -* If the type is a container based application, ask the user if they would like to deploy to Cloud Run or Google Kubernetes Engine (GKE). - * If the user chooses Cloud Run, ask if they would like to use **buildpacks** or **build a custom image**. - * If buildpacks, follow **Workflow B: Google Cloud Run With Buildpacks**. - * If custom image, follow **Workflow C: Google Cloud Run From Image**. Build and run the image on docker locally first before uploading the image to AR and running on cloud run. - * If the user chooses GKE, follow **Workflow D: Google Kubernetes Engine (GKE)**. +* If the type is a container-based/server-side application, ask the user if they would like to deploy to Cloud Run or Google Kubernetes Engine (GKE). + * If the user chooses Cloud Run, ask if they would like to use: + * **buildpacks** (follow **Workflow B: Google Cloud Run With Buildpacks**) + * **build a custom image** (follow **Workflow C: Google Cloud Run From Image**) + * **no-build deployment** (deploy source directly without building; follow **Workflow D: Google Cloud Run No-Build Deployment**) + * If the user chooses GKE, follow **Workflow E: Google Kubernetes Engine (GKE)**. ## Workflow A: Google Cloud Storage @@ -78,7 +79,30 @@ Your job is to deploy the user's applications to Cloud Run from an image. 7. **Deploy**: Deploy the built application to Google Cloud Run using the `deploy_cloudrun_service_from_image` tool and return the URL of the deployed application. -## Workflow D: Google Kubernetes Engine (GKE) +## Workflow D: Google Cloud Run No-Build Deployment + +This workflow is for deploying applications directly to Google Cloud Run without a build step, utilizing pre-configured Google-managed runtime base images. + +### Why Choose No-Build Deployment? +* **Sub-second Build Times**: Bypasses building container layers entirely, substantially speeding up deployment cycles. +* **Simpler Developer Experience**: Eliminates the need for a local Docker daemon, dockerfiles, or Cloud Build triggers. +* **Predictable Environments**: Runs on Google-managed, secured, and optimized runtime base images (such as `nodejs24`, `python314`, and `osonly24`). +* **Vendor-Locking/Pre-Compilation Support**: Great for compiled binaries (Go) and standard scripting runtimes with bundled dependencies. + +### Prerequisites & Intent Analysis: +* **Node.js**: Project must contain `package.json` and `index.js`. +* **Python**: Project must contain an entry point (e.g., `main.py`) and `requirements.txt` (create it if missing and verify local behavior). +* **Go**: Project must compile a Linux-targeted binary (e.g., `GOOS="linux" GOARCH=amd64 go build main.go`). +* **Other Languages**: Bypassing build for other unsupported languages is outside the scope of automated detection. However, if the user explicitly requests it, proceed by guiding the user to manually compile or package dependencies locally first, then use the generic OS-only base image (`osonly24`). + +### Mandatory Operational Protocol: +1. **Read Detailed Guide (MANDATORY FIRST STEP)**: Before executing any deployment commands, installing packages, compiling binaries, or calling the `deploy_cloudrun_service_no_build` tool, you **MUST** call the `view_file` tool to read the detailed [Google Cloud Run No-Build Deployment Guide](references/cloudrun/nobuild.md) in full. Failure to read this file first is a critical protocol violation. +2. **Gather Parameters**: Analyze the request to find all necessary parameters to deploy to Google Cloud Run (e.g., `project_id`, `service_name`, `region`). +3. **Clarify if Needed**: If any mandatory parameters are missing, you MUST ask the user for them before proceeding. Ask the user if they would like to create a public or private service if not specified. +4. **Deploy**: Deploy the application to Google Cloud Run using the `deploy_cloudrun_service_no_build` MCP tool. Ensure you specify the correct parameters (e.g., `project_id`, `location`, `service_name`, `source`, `base_image`, `command`, `args`, `env_vars`, `port`, and `allow_public_access`) as detailed in the reference guide, then return the URL of the deployed application. + + +## Workflow E: Google Kubernetes Engine (GKE) This workflow is for deploying container-based applications to a GKE cluster. Consult the `references/how_to_deploy_to_gke_with_kubectl.md` file for detailed `gcloud` and `kubectl` commands and best practices. @@ -113,6 +137,7 @@ First, analyze the user's application to determine the type of application. Proc * **Follow Instructions**: Your primary directive is to follow the plan or the user's direct command without deviation. * **Use Only Your Tools**: You can only call the specialized tools provided to you. +* **Mandatory No-Build Reference Reading**: If Workflow D (No-Build) is selected, you **MUST** call the `view_file` tool to read `references/cloudrun/nobuild.md` **BEFORE** installing dependencies, building binaries, or executing the `deploy_cloudrun_service_no_build` tool. Skipping this file read step constitutes an operational failure. ### **Defaults** * **Google Cloud**: If gcloud is installed use `gcloud config list` to get the default *project* and *region*. diff --git a/skills/google-cicd-deploy/references/cloudrun/nobuild.md b/skills/google-cicd-deploy/references/cloudrun/nobuild.md new file mode 100644 index 0000000..3530d68 --- /dev/null +++ b/skills/google-cicd-deploy/references/cloudrun/nobuild.md @@ -0,0 +1,108 @@ +# Google Cloud Run No-Build Deployment Guide + +Deploying your application to Google Cloud Run usually involves building a container image (via a local Docker daemon or Cloud Build) and then deploying that image. However, for supported languages, you can deploy your source code **directly** to Cloud Run without a container build step by using a pre-configured Google-managed runtime base image. + +--- + +## MCP Tool Interface + +To perform a no-build deployment, call the MCP tool `deploy_cloudrun_service_no_build`. This tool executes the deployment under the hood and returns the resulting Cloud Run service object. + +### Interactive Parameter Constraints: +1. **Mandatory Fields**: Before invoking the tool, you **MUST** ask the user to provide any required arguments (such as `project_id`, `location`, `service_name`) that are not explicitly specified in the conversation before or naturally discoverable in the repository context. Do not assume or guess missing mandatory values. +2. **Optional Fields**: For optional fields (such as `port`, `allow_public_access`, `command`, `args`, or `env_vars`), prepare reasonable defaults based on the project's language guide below, present these defaults clearly to the user, and ask for explicit confirmation before calling the tool. + +### Tool Arguments: +* **`project_id`**: The Google Cloud project ID. +* **`location`**: The location/region where your service is deployed (e.g., `us-central1`). +* **`service_name`**: The name of your Cloud Run service. +* **`source`**: The location of your application on the local file system (usually `.`). +* **`base_image`**: The runtime base image you want to use (e.g., `nodejs24`, `python314`, or `osonly24`). +* **`command`** (optional): The entry point command that the container starts up with. +* **`args`** (optional array of strings): The argument(s) to pass to the startup command. +* **`env_vars`** (optional map): Environment variables (e.g., `{"PYTHONPATH": "./vendor"}`). +* **`port`** (optional integer): The container port to listen on. +* **`allow_public_access`** (optional boolean): If the service should be public. Default is `false`. + +--- + +## Language-Specific Detailed Guides + +### Node.js No-Build Deployment Guide + +#### 1. Prerequisites & Checklist +* **Active Files**: The root of your application MUST contain `package.json` and `index.js`. +* **Node.js Base Image**: The default base image is `nodejs24` (or similar version matching your project requirements). + +#### 2. Step-by-Step Workflow +1. **Install Dependencies Locally**: + Before deploying, run `npm install` in your local workspace root. This ensures all dependencies listed in `package.json` are installed inside your `./node_modules` directory: + ```bash + npm install + ``` +2. **Deploy via MCP Tool**: + Call the `deploy_cloudrun_service_no_build` MCP tool with the following parameters: + * **`project_id`**: The Google Cloud project ID. + * **`location`**: The region where your service is deployed. + * **`service_name`**: Replace with the desired service name. + * **`source`**: `.` + * **`base_image`**: `nodejs24` + * **`command`**: `node` + * **`args`**: `["index.js"]` + * **`allow_public_access`**: `true` (if you want it to be a public service) + +--- + +### Python No-Build Deployment Guide + +#### 1. Prerequisites & Checklist +* **Identify Entry Point**: Locate the startup file for your application (typically `main.py`). +* **Requirements Specification**: Ensure there is a `requirements.txt` file in the root directory. If missing, scan the project imports to generate a correct `requirements.txt` (e.g., `pipreqs` or manual entry) and verify that running the app locally with these requirements works successfully. +* **Python Base Image**: The default base image is `python314` (or matching your Python major/minor version). + +#### 2. Step-by-Step Workflow +1. **Install Dependencies Locally**: + Since there is no build step on Cloud Run, all external dependencies must be packaged alongside your application source code. To avoid system-level `pip` permission restrictions, always create an isolated virtual environment (e.g. `.venv`), activate it to use its private `pip` to stage dependencies into a dedicated vendor folder (e.g. `./vendor`), and then deactivate: + ```bash + python3 -m venv .venv + source .venv/bin/activate + pip install -r requirements.txt --target=./vendor + deactivate + ``` +2. **Deploy via MCP Tool**: + Call the `deploy_cloudrun_service_no_build` MCP tool with the following parameters: + * **`project_id`**: The Google Cloud project ID. + * **`location`**: The region where your service is deployed. + * **`service_name`**: Replace with the desired service name. + * **`source`**: `.` + * **`base_image`**: `python314` + * **`command`**: `python` + * **`args`**: `["main.py"]` + * **`env_vars`**: `{"PYTHONPATH": "./vendor"}` + * **`allow_public_access`**: `true` (if you want it to be a public service) + +--- + +### Go No-Build Deployment Guide + +#### 1. Prerequisites & Checklist +* **Go compiler**: Must be installed locally on your machine. +* **Linux-targeted Binary**: Since Cloud Run runs containerized Linux environments, you must compile your Go binary for the Linux OS and AMD64 architecture (`linux/amd64`). +* **OS-only Base Image**: The deploy command uses `osonly24` (a base image containing only the operating system without pre-installed language runtime tools) to execute your pre-compiled binary. + +#### 2. Step-by-Step Workflow +1. **Compile the Binary Locally**: + Build the Go binary by targeting Linux OS (`linux/amd64`). Replace `main.go` with your project's actual entry point filename if different: + ```bash + GOOS="linux" GOARCH=amd64 go build -o main main.go + ``` +2. **Deploy via MCP Tool**: + Call the `deploy_cloudrun_service_no_build` MCP tool with the following parameters: + * **`project_id`**: The Google Cloud project ID. + * **`location`**: The region where your service is deployed. + * **`service_name`**: Replace with the desired service name. + * **`source`**: `.` + * **`base_image`**: `osonly24` + * **`command`**: `./main` + * **`allow_public_access`**: `true` (if you want it to be a public service) +