How to call circleCI environment variable in an Angular 2+ project?
Asked Answered
H

2

1

I have an angular project that has an api-keys.ts file that looks like this:

export var masterFirebaseConfig = {apiKey: $fireBaseApiKey, authDomain: 'dataJitsu.firebaseapp.com',databaseURL: 'https://datajitsu.firebaseio.com',storageBucket: '',messagingSenderId: '495992924984'};

I think the $fireBaseApiKey is stored as an environment variable in my project on circleCI, as you can see in the picture here:

enter image description here

However, I still get the following error when I run my configuration on circleCI:

ERROR in src/app/api-keys.ts(1,44): error TS2304: Cannot find name '$fireBaseApiKey'. src/app/app.module.ts(75,11): error TS2304: Cannot find name 'apiKey'.

(The error in app.module.ts comes directly from the error in api-keys.ts)

I tried to figure out whether the problem was on the circleCI side or with how I was plugging it into Angular, so I tried to echo out the environmental variable in my configuration file:

version: 2.1
orbs:
  cypress: cypress-io/[email protected]
steps:
  - run:
      name: Setup Environment Variables
      command: |
        echo '$fireBaseApiKey'
workflows:
  build:
    jobs:
      - cypress/install:
          build: 'npm run build'
          context: fireBaseApiKey
      - cypress/run:
          requires:
            - cypress/install
          start: 'npm start'
          context: fireBaseApiKey

I ssh'ed into the session after it errored out, and I couldn't see any indication that my echo command was even acknowledged.

I am hopeful that help on the echo front or on the Angular front will be productive to address the question/problem.

Furthermore, I am using cypress for integration testing and thus am using Cypress's orb for setting up and running the tests. I wasn't sure how to/whether environment variables to infiltrate orb jobs, so I also added the variable to a context for the project (with both the context and the key of the lone key-value pair having the same name):

enter image description here

Update: here is the output from the circleCI log file:

0 info it worked if it ends with ok 1 verbose cli [ '/usr/local/bin/node', '/usr/local/bin/npm', 'run', 'build' ] 2 info using [email protected] 3 info using [email protected] 4 verbose run-script [ 'prebuild', 'build', 'postbuild' ] 5 info lifecycle [email protected]~prebuild: [email protected] 6 info lifecycle [email protected]~build: [email protected] 7 verbose lifecycle [email protected]~build: unsafe-perm in lifecycle true 8 verbose lifecycle [email protected]~build: PATH: /usr/local/lib/node_modules/npm/node_modules/npm-lifecycle/node-gyp-bin:/root/project/node_modules/.bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 9 verbose lifecycle [email protected]~build: CWD: /root/project 10 silly lifecycle [email protected]~build: Args: [ '-c', 'ng build' ] 11 silly lifecycle [email protected]~build: Returned: code: 1 signal: null 12 info lifecycle [email protected]~build: Failed to exec build script 13 verbose stack Error: [email protected] build: ng build 13 verbose stack Exit status 1 13 verbose stack at EventEmitter. (/usr/local/lib/node_modules/npm/node_modules/npm-lifecycle/index.js:301:16) 13 verbose stack at EventEmitter.emit (events.js:182:13) 13 verbose stack at ChildProcess. (/usr/local/lib/node_modules/npm/node_modules/npm-lifecycle/lib/spawn.js:55:14) 13 verbose stack at ChildProcess.emit (events.js:182:13) 13 verbose stack at maybeClose (internal/child_process.js:962:16) 13 verbose stack at Process.ChildProcess._handle.onexit (internal/child_process.js:251:5) 14 verbose pkgid [email protected] 15 verbose cwd /root/project 16 verbose Linux 4.4.0-141-generic 17 verbose argv "/usr/local/bin/node" "/usr/local/bin/npm" "run" "build" 18 verbose node v10.13.0 19 verbose npm v6.4.1 20 error code ELIFECYCLE 21 error errno 1 22 error [email protected] build: ng build 22 error Exit status 1 23 error Failed at the [email protected] build script. 23 error This is probably not a problem with npm. There is likely additional logging output above. 24 verbose exit [ 1, true ]

Headward answered 19/1, 2019 at 3:27 Comment(0)
H
0

Ok, I finally figured it out, although probably in a hacky way. I just used sed to substitute my environment variable into my api-keys.ts file.

So, here's the new config.yml script (note the extensive changes, including wait-on: 'http-get://localhost:4200' (note the http-get there instead of http!).

version: 2.1
orbs:
  cypress: cypress-io/[email protected]
jobs:
  build:
    working_directory: ~/project
    docker:
      - image: circleci/node:9.6.1-browsers
    environment:
      circleCiApiKey: fireBaseApiKey
    steps:
      - checkout
      - run:
          name: Show current branch
          command: |
            echo ${CIRCLE_BRANCH}
            ls -larth
            echo $fireBaseApiKey
            cat src/app/api-keys.ts
            sed -i "s/circleCiApiKey/$fireBaseApiKey/g" src/app/api-keys.ts
            cat src/app/api-keys.ts
      - restore_cache:
          keys:
            - v1-dependencies-{{checksum "package.json"}}
            - v1-dependencies-
      - run:
          name: Install local dependencies
          command: |
            npm install
      - save_cache:
          key: v1-dependencies-{{checksum "package.json"}}
          paths:
            - node_modules
      - run:
          name: Building
          command: npm run build
      - save_cache:
          key: v1-dist-{{ .Environment.CIRCLE_BRANCH}}-{{ .Environment.CIRCLE_SHA1}}
          paths:
            - dist
workflows:
  version: 2.1
  build:
    jobs:
      - build
      - cypress/install:
          requires:
            - build
          build: 'npm run build'
      - cypress/run:
          requires:
            - cypress/install
            - build
          start: 'npm start'
          store_artifacts: true
          wait-on: 'http-get://localhost:4200'

The substitution occurs on the sed -i "s/circleCiApiKey/$fireBaseApiKey/g" src/app/api-keys.ts line.

The api-keys.ts file, in turn contains:

export var masterFirebaseConfig = {
    apiKey: "circleCiApiKey",
    authDomain: "dataJitsu.firebaseapp.com",
    databaseURL: "https://datajitsu.firebaseio.com",
    storageBucket: "",
    messagingSenderId: "495992924984"
  };

export var masterStripeConfig = {
  publicApiTestKey: "xxxxx",
  secretApiTestKey: "xxxxx",
  publicApiKey: "",
  secretApiKey: ""
};
Headward answered 16/2, 2019 at 5:59 Comment(0)
R
1

Have you tried echo $fireBaseApiKey (without quotes)?

To troubleshoot CircleCI, it's useful to launch an image locally.

Example: the command below will launch a local ubuntu instance with an environment variable fireBaseApiKey set to asdf-asdf-asdf. Your local files will be mounted in /usr/src/app.

docker run -it -e fireBaseApiKey=asdf-asdf-asdf -v $PWD:/usr/src/app ubuntu bash

To check your environment variable, try:

echo $fireBaseApiKey

cd /usr/src/app and run your build script, step by step. I find it useful to troubleshoot builds failing for unknown reasons.

Rosabelle answered 19/1, 2019 at 22:25 Comment(3)
Thanks, @Andre Castoldi! I can see my environment variable in the local ubuntu instance per your instructions above, but I still can't see it in my log files on circleCI when I remove the single quotes. I'll be sure to add what I see in my circleCI logfile above.Headward
Also, the local ubuntu instance looks like it doesn't have npm installed, etc., which all seem to be taken care of with the cypress orb in my config. file. I see theoretically how using a local ubuntu instance would be helpful for troubleshooting, but I'm afraid I'm not equipped to figure out how to run orbs locally.Headward
In any case, I think what is really needed is an example of how someone else runs cypress on their angular project while keeping API keys private by using environment variables. I can't seem to find a good example of that (in particular, what the config scrip would look like).Headward
H
0

Ok, I finally figured it out, although probably in a hacky way. I just used sed to substitute my environment variable into my api-keys.ts file.

So, here's the new config.yml script (note the extensive changes, including wait-on: 'http-get://localhost:4200' (note the http-get there instead of http!).

version: 2.1
orbs:
  cypress: cypress-io/[email protected]
jobs:
  build:
    working_directory: ~/project
    docker:
      - image: circleci/node:9.6.1-browsers
    environment:
      circleCiApiKey: fireBaseApiKey
    steps:
      - checkout
      - run:
          name: Show current branch
          command: |
            echo ${CIRCLE_BRANCH}
            ls -larth
            echo $fireBaseApiKey
            cat src/app/api-keys.ts
            sed -i "s/circleCiApiKey/$fireBaseApiKey/g" src/app/api-keys.ts
            cat src/app/api-keys.ts
      - restore_cache:
          keys:
            - v1-dependencies-{{checksum "package.json"}}
            - v1-dependencies-
      - run:
          name: Install local dependencies
          command: |
            npm install
      - save_cache:
          key: v1-dependencies-{{checksum "package.json"}}
          paths:
            - node_modules
      - run:
          name: Building
          command: npm run build
      - save_cache:
          key: v1-dist-{{ .Environment.CIRCLE_BRANCH}}-{{ .Environment.CIRCLE_SHA1}}
          paths:
            - dist
workflows:
  version: 2.1
  build:
    jobs:
      - build
      - cypress/install:
          requires:
            - build
          build: 'npm run build'
      - cypress/run:
          requires:
            - cypress/install
            - build
          start: 'npm start'
          store_artifacts: true
          wait-on: 'http-get://localhost:4200'

The substitution occurs on the sed -i "s/circleCiApiKey/$fireBaseApiKey/g" src/app/api-keys.ts line.

The api-keys.ts file, in turn contains:

export var masterFirebaseConfig = {
    apiKey: "circleCiApiKey",
    authDomain: "dataJitsu.firebaseapp.com",
    databaseURL: "https://datajitsu.firebaseio.com",
    storageBucket: "",
    messagingSenderId: "495992924984"
  };

export var masterStripeConfig = {
  publicApiTestKey: "xxxxx",
  secretApiTestKey: "xxxxx",
  publicApiKey: "",
  secretApiKey: ""
};
Headward answered 16/2, 2019 at 5:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.