As is often the case, I was wrong assuming everything worked in the last post . The build worked and it was automatically deployed, but after clearing the cache all that appeared was the default nginx page:

nginx

This means two things:

  1. The build succeeded - otherwise the deployment wouldn’t have started
  2. The deployment worked - the script that passes the ${PORT} env var must be working because nginx runs on port 80 by default, but Cloud Run calls port 8080 on the container

This was also a case of ‘it worked locally!’ - when doing the manual deployment , everything worked as expected. Since the deployment is working, this clearly seems like a build issue.

Hugo

Taking a look at the Cloud Build logs, one thing immediately pops out:

Step #0 - "Build": Start building sites … 
Step #0 - "Build": WARN 2021/05/18 20:31:52 found no layout file for "HTML" for kind "page": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.
Step #0 - "Build": WARN 2021/05/18 20:31:52 found no layout file for "HTML" for kind "home": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.
Step #0 - "Build": WARN 2021/05/18 20:31:52 found no layout file for "HTML" for kind "section": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.
Step #0 - "Build": WARN 2021/05/18 20:31:52 found no layout file for "HTML" for kind "taxonomy": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.
Step #0 - "Build": WARN 2021/05/18 20:31:52 found no layout file for "HTML" for kind "taxonomy": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.
Step #0 - "Build": 
Step #0 - "Build":                    | EN  
Step #0 - "Build": -------------------+-----
Step #0 - "Build":   Pages            |  4  
Step #0 - "Build":   Paginator pages  |  0  
Step #0 - "Build":   Non-page files   |  0  
Step #0 - "Build":   Static files     |  1  
Step #0 - "Build":   Processed images |  0  
Step #0 - "Build":   Aliases          |  0  
Step #0 - "Build":   Sitemaps         |  1  
Step #0 - "Build":   Cleaned          |  0  
Step #0 - "Build": 
Step #0 - "Build": Total in 31 ms

In addition to the warnings, this is fewer pages than generated by the ‘manual’ build:

                   | EN  
-------------------+-----
  Pages            | 10  
  Paginator pages  |  0  
  Non-page files   |  0  
  Static files     |  1  
  Processed images |  0  
  Aliases          |  2  
  Sitemaps         |  1  
  Cleaned          |  0 

I know very little about Hugo, but the first thing that popped into mind was the theme. Per the docs , I used git submodule to add the theme, which allows for including the theme but keeping commits separate. Reading up on submodule , it turns out that git clone does not by default copy files from submodules.

Assuming that this was the issue, I git cloned the repo and ran hugo:

$ git clone https://github.com/RocketDonkey/site.git
$ cd site
$ hugo
Start building sites … 

**<Same warnings>**

                   | EN  
-------------------+-----
  Pages            |  4  
  Paginator pages  |  0  
  Non-page files   |  0  
  Static files     |  1  
  Processed images |  0  
  Aliases          |  0  
  Sitemaps         |  1  
  Cleaned          |  0  

Total in 22 ms
$ echo $?
0

Note two things: this is the same result as the ‘failed’ build, and the exit code of the hugo command is 0, which means Hugo (and therefore Cloud Build) considers the build successful. As the final test, starting over and using:

$ git clone https://github.com/RocketDonkey/site.git --recurse-submodule

Worked as expected.

Cloud Build

The fix should be simple enough - update the automated build to pass --recurse-submodules to the git clone command it must run. Unfortunately, a quick search returned a known issue .

There are a few workarounds, and all involve modifying cloudbuild.yaml. However this would require adding a cloudbuild.yaml to the site’s repo - right now this is handled by <magic> on the Cloud side.

Before adding a cloudbuild.yaml, it is worth checking into the existing <magic> to see if a step could be added. Clicking around the UI, the Edit continuous deployment button from Cloud Run redirects to a Cloud Build trigger , and under the Configuration section there is an Open editor option. Opening that shows the build config the trigger is using:

steps:
  - name: gcr.io/cloud-builders/docker
    args:
      - build
      - '--no-cache'
      - '-t'
      - '$_GCR_HOSTNAME/$PROJECT_ID/$REPO_NAME/$_SERVICE_NAME:$COMMIT_SHA'
      - .
      - '-f'
      - Dockerfile
    id: Build
  - name: gcr.io/cloud-builders/docker
    args:
      - push
      - '$_GCR_HOSTNAME/$PROJECT_ID/$REPO_NAME/$_SERVICE_NAME:$COMMIT_SHA'
    id: Push
  - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk:slim'
    args:
      - run
      - services
      - update
      - $_SERVICE_NAME
      - '--platform=managed'
      - '--image=$_GCR_HOSTNAME/$PROJECT_ID/$REPO_NAME/$_SERVICE_NAME:$COMMIT_SHA'
      - >-
                --labels=managed-by=gcp-cloud-build-deploy-cloud-run,commit-sha=$COMMIT_SHA,gcb-build-id=$BUILD_ID,gcb-trigger-id=$_TRIGGER_ID,$_LABELS
      - '--region=$_DEPLOY_REGION'
      - '--quiet'
    id: Deploy
    entrypoint: gcloud
images:
  - '$_GCR_HOSTNAME/$PROJECT_ID/$REPO_NAME/$_SERVICE_NAME:$COMMIT_SHA'

Using this suggestion, I applied copy-paste technology to add the step to the beginning of the build config:

steps:
  - name: gcr.io/cloud-builders/git
    args:
      - submodule
      - update
      - '--init'
      - '--recursive'
  - name: gcr.io/cloud-builders/docker
    ...

Shockingly, this worked on the first try - after saving and then pushing a test commit, the site built correctly and automatically deployed.

Takeaways

Continuous deployment (f.k.a. <magic>) is implemented by generating a build trigger, and that trigger can be modified if needed. In retrospect I’m glad I hit an issue here because it resulted in a slightly better understanding of a few things (git submodules, the interaction between Cloud Build/Run, etc.).