Skip to content

Bare 'gcloud run deploy --source .' picks up an injected cloudbuild.yaml that is not in the working tree #30

@krisrowe

Description

@krisrowe

Problem

On a workstation where gapp has been used to deploy a solution, subsequent bare gcloud run deploy --source . invocations — run directly against the same or a related solution's source tree — produce a source tarball that contains a cloudbuild.yaml which does not exist in the working directory.

The injected cloudbuild.yaml defines a Docker-based build with a gapp-specific template:

steps:
  - name: 'gcr.io/cloud-builders/docker'
    args:
      - 'build'
      - '--build-arg'
      - 'ENTRYPOINT=${_ENTRYPOINT}'
      - '-t'
      - '${_IMAGE}'
      - '.'
images:
  - '${_IMAGE}'

And Cloud Build's resulting Dockerfile uses a gapp-flavored CMD that dispatches on ${ENTRYPOINT} — including a branch for __mcp_app_serve__ that runs mcp-app serve (which is not a command in the mcp-app framework's CLI).

The result: a user who expects gcloud run deploy --source . with their own local Dockerfile to work is instead getting a gapp-templated build that fails at container start time.

Reproduction

  1. On a workstation with gapp installed and set up (gapp setup <project> previously run)
  2. In a repo that has a gapp.yaml but no cloudbuild.yaml and no Dockerfile
  3. Run gcloud run deploy <service-name> --source .
  4. Observe: Cloud Build log shows steps from a cloudbuild.yaml that isn't in the repo; final image has a gapp-templated CMD

Verified by comparing the working tree (ls -la cloudbuild.yaml → not found) against the source tarball gcloud uploaded to gs://<project>_cloudbuild/source/*.tgz (contains cloudbuild.yaml).

Why it matters

  • Users trying to deploy via bare gcloud are getting a gapp-flavored build without consenting to it
  • The injected build assumes mcp-app serve as the default entry point, which fails for any solution whose CLI command isn't literally mcp-app (every mcp-app solution has a branded CLI like <app-name>-mcp serve)
  • A user's local Dockerfile is silently ignored in favor of the gapp template
  • Root cause is not discoverable from the solution repo — the injection source is somewhere on the workstation or in gapp's gcloud configuration

Investigation leads

  • Could be a gcloud extension, alias, or custom command that gapp installed
  • Could be a .gcloudignore or cloudbuild.yaml template gapp drops somewhere outside the repo
  • Could be that gapp setup modifies ~/.config/gcloud/ or a gcloud profile to inject defaults
  • Could be Cloud Build itself caching / defaulting based on prior builds in the same project's Artifact Registry

The solution tarball gcloud actually uploaded (available in the project's _cloudbuild GCS bucket) contains the injected cloudbuild.yaml, confirming the injection happens client-side before upload, not server-side during build.

Proposed direction

  1. Identify the injection source (gapp-side, gcloud-side, or filesystem-side)
  2. Ensure that either:
    • gapp's template injection is opt-in (only active when the user explicitly runs gapp commands, not when they run bare gcloud), or
    • The injection is loud — emits a clear message so the user knows gapp is influencing their gcloud deploy
  3. Document the behavior in gapp's README / setup docs if it's intentional, so users know bare gcloud run deploy --source . on a gapp-set-up workstation behaves differently than on a clean one

Priority

Medium. Not blocking gapp users' primary workflow (which is gapp deploy). But surprising and painful for anyone who wants to use gapp as one option while also supporting bare gcloud deploys on the same workstation.

Work breakdown

  • Trace the origin of the injected cloudbuild.yaml — grep ~/.config/gcloud/, inspect gapp's install footprint, check if gapp registers a gcloud extension
  • Decide: is this intentional, a bug, or a footgun to fix
  • If intentional: document clearly that gapp setup modifies bare gcloud behavior on the workstation
  • If bug / footgun: isolate gapp's injection to only gapp-invoked gcloud calls, not user-invoked ones

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions