Use globally installed npm packages in subsequent steps in cloudbuild.yaml

Hi, I’m trying to write a cloudbuild.yaml file to deploy a number of applications inside a monorepo to Firebase and Google Cloud Services. My project uses pnpm, so I have created a custom Dockerfile to install, and it will also install gcloud for use in the cloud build steps.

My issue is that I have a step that installs the npm packages firebase-tools and @sentry/cli globally for use in the build and deploy scripts in future steps, but the globally installed packages are not available in those future steps.

Here’s my Dockerfile

FROM node:20.11.1

ENV SHELL=/bin/bash
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"

RUN --mount=type=cache,id=pnpm,target=/pnpm

# Install pnpm
RUN corepack enable

# Setup pnpm
RUN pnpm setup

ENTRYPOINT ["bash"]

and my cloudbuild.yaml

timeout: 3600s

options:
  machineType: 'E2_HIGHCPU_8'

substitutions:
  _BUILD_ENV: 'dev'
  _DEPLOY_ENV: 'dev'
  _FIREBASE_ALIAS: 'test'

steps:
  - id: '? Installing dependencies with pnpm'
    name: 'charliefrancis/pnpm:latest'
    entrypoint: 'bash'
    dir: '/workspace'
    args: ['-c', 'pnpm install --frozen-lockfile']

  - id: '? Adding global packages'
    name: 'charliefrancis/pnpm:latest'
    entrypoint: 'bash'
    dir: '/workspace'
    args: ['-c', 'pnpm add --global firebase-tools@latest @sentry/cli@latest']

  - id: '? Building app-web'
    name: 'charliefrancis/pnpm:latest'
    entrypoint: 'bash'
    dir: '/workspace'
    args: ['-c', 'pnpm run --filter app-web build:$_BUILD_ENV']

  - id: '? Deploying app-web'
    name: 'charliefrancis/pnpm:latest'
    entrypoint: 'bash'
    dir: '/workspace'
    args: ['-c', 'pnpm run --filter app-web deploy:only:$_BUILD_ENV']

  - id: '? Deploying sourcemaps for app-web'
    name: 'charliefrancis/pnpm:latest'
    entrypoint: 'bash'
    dir: '/workspace'
    args: ['-c', 'pnpm run --filter app-web sourcemaps:deploy:$_BUILD_ENV']

  - id: '?️ Deploying app-cloud-functions'
    name: 'charliefrancis/pnpm:latest'
    entrypoint: 'bash'
    dir: '/workspace'
    args: ['-c', 'pnpm run --filter app-cloud-functions deploy:$_DEPLOY_ENV']

  - id: '? Deploying app-assistants'
    name: 'charliefrancis/pnpm:latest'
    entrypoint: 'bash'
    dir: '/workspace'
    args: ['-c', 'gcloud run deploy app-assistants --source --region europe-west2 --allow-unauthenticated --set-secrets=[OPENAI_API_KEY=openai_api_key:latest]']

  - id: '? Deploying Storybook'
    name: 'charliefrancis/pnpm:latest'
    entrypoint: 'bash'
    dir: '/workspace'
    args:
      - '-c'
      - |
        if [ "$_BUILD_ENV" == "dev" ]; then \
          pnpm run --filter app-web deploy:storybook; \
        else \
          echo -e "\n⏭ Skipping Storybook deployment for non-development environment."; \
        fi"]

The fourth step Deploying app-web then fails

Already have image (with digest): charliefrancis/pnpm:latest
> bunk-web@6.0.1 deploy:only:dev /workspace/bunk-web
> firebase use test && pnpm run optimise && pnpm run deploy:app

sh: 1: firebase: not found
/workspace/bunk-web:
 ERR_PNPM_RECURSIVE_RUN_FIRST_FAIL  bunk-web@6.0.1 deploy:only:dev: `firebase use test && pnpm run optimise && pnpm run deploy:app`
spawn ENOENT

Is there a way to make the globally installed packages available for the other steps?

1 Like

So the only solution I found to this is to install the global dependencies in the Dockerfile, which will then be available in the container image.

FROM node:20.11.1

ENV SHELL=/bin/bash
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"

RUN --mount=type=cache,id=pnpm,target=/pnpm

# Install pnpm
RUN corepack enable

# Setup pnpm
RUN pnpm setup

# Install global dependencies
pnpm add --global firebase-tools@latest @sentry/cli@latest

ENTRYPOINT ["bash"]
1 Like