google-cloud-build

How do I get the version from package.json and use it in my Cloud Build step to tag a Docker image?


I would like to build and tag a Docker image with the version value from my Node.js app's package.json

I currently tag the image with the commit details and would like to add an additional version tag like v.1.0.1

Example build.yaml

steps:
  # Build the container image
  - name: ${_BUILDER_DOCKER}
    args: [ 'build', '-t', '${_IMAGE}:${_IMAGE_TAG}', '-t', '${_IMAGE}:latest', '.' ]

  # Push the container image to Container Registry
  - name: ${_BUILDER_DOCKER}
    args: [ 'push', '${_IMAGE}', '--all-tags']

  # Deploy container image to Cloud Run
  - name: ${_BUILDER_GCLOUD}
    entrypoint: gcloud
    args:
      - 'run'
      - 'deploy'
      - 'build-demo'
      - '--image'
      - '${_IMAGE}:${_IMAGE_TAG}'
      - '--region'
      - 'us-west2'
      - '--platform'
      - 'managed'
      - '--port'
      - '3000'
      - '--allow-unauthenticated'

options:
  automapSubstitutions: true
  logging: CLOUD_LOGGING_ONLY
substitutions:
  _BUILDER_GCLOUD: gcr.io/google.com/cloudsdktool/cloud-sdk
  _BUILDER_DOCKER: gcr.io/cloud-builders/docker
  _IMAGE_TAG: '${SHORT_SHA}_${BUILD_ID}'
  _IMAGE: 'us-west2-docker.pkg.dev/${PROJECT_ID}/demo/dev/build-demo'
timeout: 300s


Solution

  • Interesting question.

    The gcr.io/cloud-builders/docker image (is this your ${_BUILDER_GCLOUD}?) includes a shell.

    You can use the shell to:

    1. extract the version value from package.json
    2. parse it
    3. provide it docker build

    Something of the form:

    steps:
      # Build the container image
      - name: ${_BUILDER_DOCKER}
        entrypoint: bash
        args:
        - -c
        - |
          #!/usr/bin/env bash
    
          # Create VERSION
          # Extract the "version": "{value}" line
          # Extract {value} from it
          VERSION=$(\
            cat package.json \
            | grep --only-matching '"version": "[^"]*' \
            | cut --delimiter='"' --fields=4)
    
          # NOTE double dollar symbol to escape variable
          echo "VERSION: $${VERSION}"
    
          # Do the build
          docker build \
          --tag=${_IMAGE}:latest \
          --tag=${_IMAGE}:${_IMAGE_TAG} \
          --tag=${_IMAGE}:$${VERSION} \
          --file=./Dockerfile \
          .
    
      # Deploy container image to Cloud Run
      ...
    

    It would be more elegant to use a tool like jq to parse package.json as JSON but using grep and cut saves installing more software in the image.