Parakoos
Parakoos

Reputation: 1323

Pass environment variables to Firebase predeploy scripts fails silently

I am trying to run a npm build during my hosting pre-deploy script.

If I was going to run the build from the command line, I can successfully run this:

set NUXT_ENV_GCLOUD_PROJECT=whatever&&npm run build

And that works just fine. But when I try the same in the following firebase.json file it simply skips the build:

{
  "hosting": {
    "predeploy": ["set NUXT_ENV_GCLOUD_PROJECT=whatever&& npm run build"],
  }
}
> firebase deploy --only hosting

=== Deploying to 'xxx'...

i  deploying hosting
Running command: set NUXT_ENV_GCLOUD_PROJECT=whatever&& npm run build
+  hosting: Finished running predeploy script.
i  hosting[dev-phojo-app]: beginning deploy...
i  hosting[dev-phojo-app]: found 41 files in ./dist

It says that it finished running the predeploy scripts, but it in fact never did. If I remove the setting of the environment variable, then it works as expected (but, of course, the build fails because the environment variable is not there..)

What is going on here?

Upvotes: 1

Views: 877

Answers (3)

SAGB
SAGB

Reputation: 109

I tried the proposed answer but it didn't work for me as I'm using nextjs and firebase. I had to modify the package.json with a new script

"deploy-hosting-preprod": "sed -i '.bak' 's/NEXT_PUBLIC_ENVIRONMENT=.*/NEXT_PUBLIC_ENVIRONMENT=live/' .env; export NEXT_PUBLIC_ENVIRONMENT=live; firebase deploy --only hosting:preprod"

Also in my firebase json instead of using predeploy I use postdeploy, to return the .env file to normal as:

{
  "hosting": [
    ...
    {
      "target": "preprod",
      "source": ".",
      "ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
      "postdeploy": ["npm run revert-env"]
    }
  ],
  ...

Upvotes: 0

Parakoos
Parakoos

Reputation: 1323

I am working in windows, so the specifics are a bit different, but in effect, yes, this worked. I made a build.bat file and there I could set environment variables that would then be picked up by the npm build script.

For anyone who might want to follow suit, this is what I ended up with:

firebase.json

"hosting": {
    "predeploy": [ ".\\build.bat" ]
}

build.bat

echo off
2>NUL CALL :CASE_%GCLOUD_PROJECT%     # jump to :CASE_x, :CASE_y, etc.
IF ERRORLEVEL 1 CALL :DEFAULT_CASE    # If label doesn't exist

rmdir /s /q dist
npm run generate
EXIT /B

:CASE_dev-myapp-app
  echo Building for hosted development, %GCLOUD_PROJECT%
  set NUXT_ENV_GCLOUD_ENV=development
  set NUXT_ENV_GCLOUD_HOSTED=true
  GOTO END_CASE
:CASE_prod-myapp-app
  echo ============= PRODUCTION BUILD FOR %GCLOUD_PROJECT% ===================
  set NUXT_ENV_GCLOUD_ENV=development
  set NUXT_ENV_GCLOUD_HOSTED=true
  GOTO END_CASE
:DEFAULT_CASE
  ECHO Unknown Google Cloud project "%GCLOUD_PROJECT%"
  exit 666
:END_CASE
  VER > NUL # reset ERRORLEVEL
  GOTO :EOF # return from CALL

That will fail if the incoming GCLOUD_PROJECT variable is not set. It will fail if it is set to an unrecognized project. And it will fail if the npm command fails.

Upvotes: 1

Doug Stevenson
Doug Stevenson

Reputation: 317292

Instead of using a shell expression in firebase.json, I suggest putting those expressions into a separate script file, and invoke that script from the predeploy hook. So, something like this:

predeploy.sh:

#!/bin/bash
export NUXT_ENV_GCLOUD_PROJECT=whatever
npm run build

firebase.json:

  "hosting": {
    "predeploy": [ "./predeploy.sh" ],
  }

Make sure that predeploy.sh is executable: chmod a+x predeploy.sh

I suspect that the Firebase CLI just wants to "exec" the command you give, and that it can't contain shell expressions, such as &&.

Upvotes: 3

Related Questions