herokuwebpackheroku-pipelines

Heroku pipeline - staging env variable carried into production


I've recently deployed a React/Express app to Heroku, but I'm having an issue with environment variables that are part of the built app and the Heroku deployment pipeline - in a nutshell, the values of environment variables from the app's staging release are being carried over when promoting to production - the only way that I can get the environment variables to set correctly is to push the app directly to production, which really defeats the purpose of the deployment pipeline in the first place. Here's a summary of the scenario:

The environment variable in question is API_URL, which is referenced in webpack.config.js like so:

plugins: [
    new webpack.DefinePlugin({
        'API_URL': JSON.stringify(process.env.API_URL || 'http://localhost:4000/api/v1')
    })
]

The API is itself another Heroku app with staging and production releases, and so the values of the API_URL environment variable are set in my React app Heroku configuration as https://staging-api-12345.herokuapp.com/api/v1 and https://production-api-12345.herokuapp.com/api/v1, respectively.

When I push my React app up to staging, it works perfectly - however, when I promote the app to production and make the first call to the API, it is still pointing to https://staging-api-12345.herokuapp.com/api/v1. Ok well, I understand why that is the case - the app was built when being pushed to staging... so I tried rebuilding the app after promoting to production, but that did not work, it still used the staging environment variables.

When using the Heroku deployment pipeline, is there a way to force the app slug to rebuild so that it will catch the different environment variables?


Solution

  • You cannot rebuild the slug, the main point of pipelines is to move the same slug between apps.

    What you need to do is to fetch API_URL at runtime and not during build process. You can put all envs in one file, for example env.js

    export const API_URL = process.env.API_URL;
    export const OTHER_VAR = process.env.OTHER_VAR;
    

    And then just import what you need in other files

    import { API_URL, OTHER_VAR } from 'env.js';