cannot access environment secrets variables passing it from GH-pages to ReactApp

Viewed 1949

I'm trying to use environment variables in ReactApp deploying at Github-pages.

The variable is added through process.env and starts with REACT_APP as docs prescribe

export default class WeatherService {
  constructor() {
    this.API_WEATHER_URL = process.env.REACT_APP_DEV_SERVER_URL + 'api/weather';
  }

and .env created with GitHub Actions yml

jobs:
  front-build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v1

      - name: Store variables
        run: |
          cd front-app
          touch .env
          REACT_APP_DEV_SERVER_URL=${{ secrets.DEV_SERVER_URL }} >> .env

      - name: Build
        run: |
          cd front-app
          npm install
          npm run-script build
      - name: Deploy
          ...

but the app gets wrong values from GitHub Secrets.

enter image description here

see the react-app at GH-pages receives a wrong object, not what i've passed ("username.cloudTech.com/api"):

this.API_BLOB_URL = Object({
                NODE_ENV: "production",
                PUBLIC_URL: "/azure-flask-react",
                WDS_SOCKET_HOST: void 0,
                WDS_SOCKET_PATH: void 0,
                WDS_SOCKET_PORT: void 0,
                FAST_REFRESH: !0
            }).REACT_APP_DEV_SERVER_URL + "api/blob/"

At the same time when I build locally with npm run build. React successfully replaces the env. variables

environmental variable replaced with react

As used to the purpose is to use different environment settings as api dev server in

  • development (127.0.0.1:5000) and
  • production (username.cloudTech.com/api).

I've already tried to use env-cmd and dotenv lib but it neither worked


UPDATE:

If I pass REACT_APP_ENV='username.cloudTech.com/api' npm script - it passes this variable successfully:

"scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "build:staging": "REACT_APP_FRONT_APP_URL=nikonov91-dev.github.io/azure-flask-react/ npm run build"
    ...
}

And then voila.

environment variable in deployed react app


UPDATE on @OldPro`s answer. I've quoted my line:

run: |
  cd front-app
  touch .env
  echo 'REACT_APP_DEV_SERVER_URL=${{ secrets.DEV_SERVER_URL }}' >> .env

but the value is still empty in JS ch: enter image description here


I've tried also the answer of @peterevans

        run: |
          cd front-app
          echo "DEV_SERVER_URL=${{ secrets.DEV_SERVER_URL }}" >> $GITHUB_ENV
          touch .env
          echo "REACT_APP_DEV_SERVER_URL=${{ env.DEV_SERVER_URL }}" >> .env

unfortunately the variable is the same


UPDATE

I'm sure my approach is working because if I hardcode the variable in YML it works as should and can be easily accessed in my Appv

 - name: Store variables
        run: |
          cd front-app
          touch .env
          echo "REACT_APP_DEV_SERVER_URL='https://first-py-app.azurewebsites.net/'" >> .env

and this.API_BLOB_URL = process.env.REACT_APP_DEV_SERVER_URL + 'api/blob/'; becomes this.API_BLOB_URL = "https://first-py-app.azurewebsites.net/api/blob/"


BUT I STILL LOOKING FOR solution how to pass variable from GH-Secrets

4 Answers

I've found out there are two approaches:

  • Repository Secrets may be set Settings->Secrets->New repository secret

  • Environment Secrets may be created Settings->Environments->New environment->Add secret

    and add to job description next argument: environment: your-wanted-env as it is in my code

Environment Secrets needs additional argument in job description:

jobs:
  trying-to-use-environment-secrets:
    runs-on: ubuntu-latest
    environment: test-env #<---The only difference we need to specify what environment to use for environment secrets
    steps:
      - name: Checkout
        uses: actions/checkout@v1

      - name: Store variables
        run: |
          echo ${{ secrets.DEV_SERVER_URL_FROM_ENVIRONMENT_SECRETS }}
          echo "DEV_SERVER_URL=${{ secrets.DEV_SERVER_URL_FROM_REPOSITORY_SECRETS }}"

Update

In your update, you say

I'm sure my approach is working because if I hardcode the variable in YML it works as should and can be easily accessed in my Appv

I ran my own test. I created a secret named DEV_SERVER_URL and set it to https://first-py-app.azurewebsites.net/

Then I ran this job:

jobs:
  env-test:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout
      uses: actions/checkout@v1

    - name: Store variables
      run: |
        mkdir front-app
        cd front-app
        touch .env
        echo 'REACT_APP_DEV_SERVER_URL=${{ secrets.DEV_SERVER_URL }}' >> .env

    - name: Leak variables
      run: |
        cd front-app
        ls -al
        cat .env
        cat .env | hexdump

It produced this output, as expected (note the *** is in the original output, as GitHub censors secrets automatically):

Output of GitHub action run

(violating the rule about posting text because I want to preserve the formatting). The important thing about this output is the hexdump at the end.

$ echo 'REACT_APP_DEV_SERVER_URL=https://first-py-app.azurewebsites.net/' | hexdump -x
0000000    4552    4341    5f54    5041    5f50    4544    5f56    4553
0000010    5652    5245    555f    4c52    683d    7474    7370    2f3a
0000020    662f    7269    7473    702d    2d79    7061    2e70    7a61
0000030    7275    7765    6265    6973    6574    2e73    656e    2f74
0000040    000a                                                        
0000041

It means the secret is being saved in the .env file as expected. So I have to conclude that your problem is that the secret DEV_SERVER_URL is either empty or not accessible to your action runner. I suggest you run the same job I did and see what results you get.


Original answer

Although pictures can be nice sometimes, they should be in addition to, not a substitute for, including code as text. People can search and edit text, but not pictures.

According to your picture, your GitHub Action includes a step like this:

run: |
  cd front-app
  touch .env
  REACT_APP_DEV_SERVER_URL=${{ secrets.DEV_SERVER_URL }} >> .env

So your first problem is that the last line above only sets the environment variable for that step and does nothing to the .env file. What you probably meant or want is

run: |
  cd front-app
  touch .env
  echo 'REACT_APP_DEV_SERVER_URL=${{ secrets.DEV_SERVER_URL }}' >> .env

That will put the assignment in the .env file. Whether that is sufficient for your needs will depend on the rest of your action.

Try using the way GitHub Actions recommends to set environment variables.

Change your "Store variables" step to look like this:

      - name: Store variables
        run: |
          echo "REACT_APP_DEV_SERVER_URL=${{ secrets.DEV_SERVER_URL }}" >> $GITHUB_ENV

Is there anything else in the .env file that you need for your react app? I'm not very familiar with ReactJS project structure, but I'm wondering why you're not using the env directive in your workflow and passing the secret in the environment variable declaration, then accessing the environment variable directly from npm run build:

jobs:
  front-build-and-deploy:
    runs-on: ubuntu-latest
    env:
      REACT_APP_DEV_SERVER_URL: ${{ secrets.DEV_SERVER_URL }}
    steps:
      ...
      # $REACT_APP_DEV_SERVER_URL is now available to any steps in the job
Related