Karlan
Karlan

Reputation: 353

How to set server/build environment variables in gatsby-config.js file with Github secrets

I'm using Firebase hosting for my Gatsby application. I use the plugin gatsby-firesource. You need to put in the firebase credentials in the options of the plugin. I use environment variables for that.When running locally all works fine. No problem building the application.

I set up an CI/CD workflow with Github actions and secrets. But I don't get it to work. The environment variables are returned undefined I've read the Gatsby documentation about setting the environment variables. I don't understand it fully. The environment variables are only necessary during the build stage. Could you help me? Thanks in advance.

My gatsby-config.js file (short version):


require('dotenv').config({
  path: `.env.${activeEnv}`,
});

module.exports = {
  siteMetadata: {
    title: 'testsite',
    siteUrl: 'testsite.co',
  },
  plugins: [
    {
      resolve: 'gatsby-firesource',
      options: {
        credential: {
          type: process.env.FIREBASE_TYPE,
          project_id: process.env.FIREBASE_PROJECT_ID,
          private_key_id: process.env.FIREBASE_PRIVATE_KEY_ID,
          private_key: process.env.FIREBASE_PRIVATE_KEY,
          client_email: process.env.FIREBASE_CLIENT_EMAIL,
          client_id: process.env.FIREBASE_CLIENT_ID,
          auth_uri: process.env.FIREBASE_AUTH_URI,
          token_uri: process.env.FIREBASE_TOKEN_URI,
          auth_provider_x509_cert_url:
            process.env.FIREBASE_AUTH_PROVIDER_X509_CERT_URL,
          client_x509_cert_url: process.env.FIREBASE_CLIENT_X509_CERT_URL,
        },
        types: [
          {
            type: 'Sound',
            collection: 'sounds',
            map: (doc) => ({
              title: doc.title,
              mp3: doc.mp3,
              WAV: doc.WAV,
            }),
          },
        ],
      },
    },
  ],
}

My Github actions yaml file:

name: Deploy to Firebase Hosting on PR
'on': pull_request
jobs:
  build_and_preview:
    runs-on: ubuntu-latest
    env:
      CI: true
    steps:
      - uses: actions/checkout@v2
      - run: |
          touch .env.production
          echo FIREBASE_TYPE: ${{ secrets.FIREBASE_TYPE }} >> .env
          echo FIREBASE_PROJECT_ID: ${{ secrets.FIREBASE_PROJECT_ID }} >> .env
          echo FIREBASE_PRIVATE_KEY_ID: ${{ secrets.FIREBASE_PRIVATE_KEY_ID }} >> .env
          echo FIREBASE_PRIVATE_KEY: ${{ secrets.FIREBASE_PRIVATE_KEY }} >> .env
          echo FIREBASE_CLIENT_EMAIL: ${{ secrets.FIREBASE_CLIENT_EMAIL }} >> .env
          echo FIREBASE_CLIENT_ID: ${{ secrets.FIREBASE_CLIENT_ID }} >> .env
          echo FIREBASE_AUTH_URI: ${{ secrets.FIREBASE_AUTH_URI }} >> .env
          echo FIREBASE_TOKEN_URI: ${{ secrets.FIREBASE_TOKEN_URI }} >> .env
          cat .env.production
          rm .gitignore
          git config user.email "[email protected]"
          git config user.name "test"
          git add .
          git commit -m "environment variables"
          npm ci && npm run test && npm run build
      - uses: FirebaseExtended/action-hosting-deploy@v0
        with:
          repoToken: '${{ secrets.GITHUB_TOKEN }}'
          firebaseServiceAccount: '${{ secrets.FIREBASE_SERVICE_ACCOUNT_TESTSITE }}'
          projectId: TESTSITE
        env:
          FIREBASE_CLI_PREVIEWS: hostingchannels 

Upvotes: 1

Views: 1000

Answers (2)

Karlan
Karlan

Reputation: 353

I saw that I copied the keys not into right file. .env instead of .env.production. I also did echo FIREBASE_TYPE: ${{ secrets.FIREBASE_TYPE }} >> .env instead of echo FIREBASE_TYPE=${{ secrets.FIREBASE_TYPE }} >> .env (= NOT :).

I don't use the gatsby-firesource plugin anymore but I use the firebase npm library. So I don't know if the new setup also works for the gatsby-firesource plugin. I think it will.

This setup worked finally (the yaml file):

# https://github.com/firebase/firebase-tools

name: Deploy to Firebase Hosting on merge
'on':
  push:
    branches:
      - main
jobs:
  build_and_deploy:
    runs-on: ubuntu-latest
    env:
      CI: true
    steps:
      - uses: actions/checkout@v2
      - run: |
          touch .env.development
          echo GATSBY_API_KEY=${{ secrets.GATSBY_API_KEY }} >> .env.development
          echo GATSBY_AUTH_DOMAIN=${{ secrets.GATSBY_AUTH_DOMAIN }} >> .env.development
          echo GATSBY_PROJECT_ID=${{ secrets.GATSBY_PROJECT_ID }} >> .env.development
          echo GATSBY_STORAGE_BUCKET=${{ secrets.GATSBY_STORAGE_BUCKET }} >> .env.development
          echo GATSBY_MESSAGING_SENDER_ID=${{ secrets.GATSBY_MESSAGING_SENDER_ID}} >> .env.development
          echo GATSBY_APP_ID=${{ secrets.GATSBY_APP_ID }} >> .env.development
          echo GATSBY_MEASUREMENT_ID=${{ secrets.GATSBY_MEASUREMENT_ID}} >> .env.development
          cat .env.development
          rm .gitignore
          git config user.email "[email protected]"
          git config user.name "username"
          git add .
          git commit -m "environment variables"
          npm ci && npm run test && npm run build
      - uses: FirebaseExtended/action-hosting-deploy@v0
        with:
          repoToken: '${{ secrets.GITHUB_TOKEN }}'
          firebaseServiceAccount: '${{ secrets.FIREBASE_SERVICE_ACCOUNT_SOUNDSFROMTHEWEB }}'
          channelId: live
          projectId: soundsfromtheweb
        env:
          FIREBASE_CLI_PREVIEWS: hostingchannels

Upvotes: 0

Ferran Buireu
Ferran Buireu

Reputation: 29335

The environment variables are only necessary during the build stage

Well, that's not exactly right. Gatsby needs environment variables as well as in the gatsby develop and in the gatsby build process. By default, it will take the .env.development and .env.production files respectively. In other words, they are needed in each compilation.

According to the documentation (and the workaround applies in all CI/CD ecosystems like Netlify), it seems that you need to add the variables in the GitHub dashboard:

enter image description here

Once created, they will be available in your GitHub actions:

steps:
  - name: Hello world action
    with: # Set the secret as an input
      super_secret: ${{ secrets.SuperSecret }}
    env: # Or as an environment variable
      super_secret: ${{ secrets.SuperSecret }}

If the approach doesn't work, try prefixing the environment variables with GATSBY_, in Netlify it's a mandatory configuration to make the variables available in the server-side, so, without knowing how GitHub actions work, if the previous approach doesn't work, you can try it in the GitHub environment, as the docs suggest:

In Node, your site has access to your API_KEY (Server-side) using the identifier process.env.API_KEY. To access it client-side, you can use a .env.* file containing API_KEY. However, you are strongly advised against checking these files into source control as it’s a security issue to expose the API key. As a more secure alternative, you can prefix your variable with GATSBY_ (as shown above). With this prefix, Gatsby automatically embeds the variable as process.env.GATSBY\_\* in compiled JS making it available in the browser context without exposing it elsewhere.

So, following the previous example, EXAMPLE_API_KEY will become GATSBY_EXAMPLE_API_KEY.

Upvotes: 1

Related Questions