Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

eas build with gitignored google-services.json file. #228

Closed
ZEAL-MATCH-LTD opened this issue Feb 6, 2021 · 39 comments
Closed

eas build with gitignored google-services.json file. #228

ZEAL-MATCH-LTD opened this issue Feb 6, 2021 · 39 comments

Comments

@ZEAL-MATCH-LTD
Copy link

ZEAL-MATCH-LTD commented Feb 6, 2021

Hello, Great tool! enjoying using it a lot.

At the moment I am having to commit my google-services.json & GoogleService-Info.plist files in order to allow the cloud-build to work properly but this seems a bit of a security risk?

Ideally, I'd have these files reference in my .gitignore

Sat, 06 Feb 2021 17:16:45 GMT
[stderr] [17:16:45] Cannot copy google-services.json from /usr/local/lib/node_modules/@expo/eas-build-worker/workingdir/build/google-services-staging.json to /usr/local/lib/node_modules/@expo/eas-build-worker/workingdir/build/android/app/google-services.json. Please make sure the source and destination paths exist.
Sat, 06 Feb 2021 17:16:45 GMT
[stderr] [17:16:45] Error: Cannot copy google-services.json from /usr/local/lib/node_modules/@expo/eas-build-worker/workingdir/build/google-services-staging.json to /usr/local/lib/node_modules/@expo/eas-build-worker/workingdir/build/android/app/google-services.json. Please make sure the source and destination paths exist.
[stderr]     at setGoogleServicesFile (/usr/local/lib/node_modules/@expo/eas-build-worker/node_modules/@expo/config-plugins/src/android/GoogleServices.ts:79:11)
Sat, 06 Feb 2021 17:16:45 GMT
[stderr]     at runMicrotasks (<anonymous>)
Sat, 06 Feb 2021 17:16:45 GMT
[stderr]     at processTicksAndRejections (internal/process/task_queues.js:93:5)
Sat, 06 Feb 2021 17:16:45 GMT
[stderr]     at /usr/local/lib/node_modules/@expo/eas-build-worker/node_modules/@expo/config-plugins/src/android/GoogleServices.ts:53:7
Sat, 06 Feb 2021 17:16:45 GMT
[stderr]     at action (/usr/local/lib/node_modules/@expo/eas-build-worker/node_modules/@expo/config-plugins/src/plugins/core-plugins.ts:118:23)
Sat, 06 Feb 2021 17:16:45 GMT
[stderr]     at action (/usr/local/lib/node_modules/@expo/eas-build-worker/node_modules/@expo/config-plugins/src/plugins/compiler-plugins.ts:282:23)
Sat, 06 Feb 2021 17:16:45 GMT
[stderr]     at evalModsAsync (/usr/local/lib/node_modules/@expo/eas-build-worker/node_modules/@expo/config-plugins/src/plugins/mod-compiler.ts:75:25)
Sat, 06 Feb 2021 17:16:45 GMT
[stderr]     at compileModsAsync (/usr/local/lib/node_modules/@expo/eas-build-worker/node_modules/@expo/config-plugins/src/plugins/mod-compiler.ts:17:10)
Sat, 06 Feb 2021 17:16:45 GMT
[stderr]     at configureManagedProjectAsync (/usr/local/lib/node_modules/@expo/eas-build-worker/node_modules/expo-cli/src/commands/apply/configureProjectAsync.ts:115:12)
Sat, 06 Feb 2021 17:16:45 GMT
[stderr]     at prebuildAsync (/usr/local/lib/node_modules/@expo/eas-build-worker/node_modules/expo-cli/src/commands/eject/Eject.ts:146:25)
Sat, 06 Feb 2021 17:16:45 GMT
[stderr]     at Object.ejectAsync (/usr/local/lib/node_modules/@expo/eas-build-worker/node_modules/expo-cli/src/commands/eject/Eject.ts:78:19)
Sat, 06 Feb 2021 17:16:45 GMT
[stderr]     at actionAsync (/usr/local/lib/node_modules/@expo/eas-build-worker/node_modules/expo-cli/src/commands/eject.ts:46:5)
Sat, 06 Feb 2021 17:16:45 GMT
[stderr]     at Command.<anonymous> (/usr/local/lib/node_modules/@expo/eas-build-worker/node_modules/expo-cli/src/exp.ts:346:7)
Sat, 06 Feb 2021 17:16:45 GMT
Build failed: node exited with non-zero code: 1

Is there any workaround to this scenario/issue?

Thank you!

@zencephalon
Copy link

It'd be nice to extend eas credentials to storing secrets in general. That way eas submit could get the Google api key file and the EXPO_APPLE_APP_SPECIFIC_PASSWORD from the Expo server.

@RadomirPerisic
Copy link

I have a similar issue, I'm using aws amplify which downloads a file aws-exports.js which is in .gitignore (as it should be). I need to include it in build without editing .gitignore.

@dsokal
Copy link
Contributor

dsokal commented Jun 15, 2021

Hi guys,

You don't need to commit the gitignored files to the repo.

Here's a workaround (assuming you want your build to have access to google-service.json):

  • Convert the secret file to a base64-encoded string:
    $ base64 google-services.json
  • Copy the output of the command and set an EAS secret with eas secret:create (e.g. GOOGLE_SERVICES_BASE64)
  • Use an EAS Build hook (https://docs.expo.io/build-reference/how-tos/#eas-build-specific-npm-hooks) to restore the file:
    In package.json:
    "eas-build-pre-install": "echo $GOOGLE_SERVICES_BASE64 | base64 --decode > /path/to/google-services.json"

@dsokal dsokal closed this as completed Jun 15, 2021
@diegoconcha
Copy link

diegoconcha commented Jan 6, 2022

@dsokal is this still the recommended way to handle this situation? I'm using amplify and also have the aws-exports.js file someone else mentioned above. This file changes based on changes we make to the backend so it's somewhat dynamic so we'd need to update it's eas secret value often. I would much rather prefer to be able to include the latest version of this file in the build vs it being ignored by eas because it's in the .gitignore. Thank you!

@dsokal
Copy link
Contributor

dsokal commented Jan 10, 2022

Hey @diegoconcha,
Yes, this is still the recommended way of handling this case. I agree this is not the most convenient way of working with Amplify. I'll open another issue to remember about this.

@wkozyra95
Copy link
Contributor

wkozyra95 commented Jan 10, 2022

@diegoconcha If you are using default git workflow (you don't have requireCommit: true in eas.json) then you can add .easignore file

Note that if easignore is present, gitingore files are not respected(even in subdirectories) and there can only be one .easignore and it has to be in the root of the repository

@diegoconcha
Copy link

diegoconcha commented Feb 15, 2022

@diegoconcha If you are using default git workflow (you don't have requireCommit: true in eas.json) then you can add .easignore file

Note that if easignore is present, gitingore files are not respected(even in subdirectories) and there can only be one .easignore and it has to be in the root of the repository

Thanks @wkozyra95 for your reply. The challenge with this approach is now we have to keep two ignore files up-to-date (.gitignore and .easignore). This approach is definitely an improvement over the base64 encoded string and eas pre-install step discussed above but it would probably be easier for most teams if expo added a .easincludes file where we can include important cloud configuration files like the aws-exports.js in our case. I hope you all consider adding this in the near future.

@AllanBengco
Copy link

@diegoconcha If you are using default git workflow (you don't have requireCommit: true in eas.json) then you can add .easignore file
Note that if easignore is present, gitingore files are not respected(even in subdirectories) and there can only be one .easignore and it has to be in the root of the repository

Thanks @wkozyra95 for your reply. The challenge with this approach is now we have to keep two ignore files up-to-date (.gitignore and .easignore). This approach is definitely an improvement over the base64 encoded string and eas pre-install step discussed above but it would probably be easier for most teams if expo added a .easincludes file where we can include important cloud configuration files like the aws-exports.js in our case. I hope you all consider adding this in the near future.

Hi @diegoconcha or @everyone here! I am currently on the process of eas build-ing an app, and I was wondering whether to use the base64 route or this .easignore. I am leaning towards the latter, but I am worried about inadvertently exposing my aws-exports.js to prying eyes. What are your thoughts about this?

@wkozyra95
Copy link
Contributor

If it's a secret it should be passed via EAS Secrets (base64 route), but if I understand correctly aws-exports.js is part of the js bundle, so anyone can extract those values by unzipping apk/ipa, so there is no point in going to far in protecting any secrets that are available client-side.

@diegoconcha
Copy link

diegoconcha commented Mar 16, 2022

@diegoconcha If you are using default git workflow (you don't have requireCommit: true in eas.json) then you can add .easignore file
Note that if easignore is present, gitingore files are not respected(even in subdirectories) and there can only be one .easignore and it has to be in the root of the repository

Thanks @wkozyra95 for your reply. The challenge with this approach is now we have to keep two ignore files up-to-date (.gitignore and .easignore). This approach is definitely an improvement over the base64 encoded string and eas pre-install step discussed above but it would probably be easier for most teams if expo added a .easincludes file where we can include important cloud configuration files like the aws-exports.js in our case. I hope you all consider adding this in the near future.

Hi @diegoconcha or @everyone here! I am currently on the process of eas build-ing an app, and I was wondering whether to use the base64 route or this .easignore. I am leaning towards the latter, but I am worried about inadvertently exposing my aws-exports.js to prying eyes. What are your thoughts about this?

Hey @AllanBengco we went the .easignore route. Ours is a copy of our .gitignore without the aws-exports.js so that the aws-exports.js is included in the build. This file only has routes and high level config of our backend so mostly stuff that's already easy to figure out by analyzing network traffic on the device or using our app. Essentially nothing we're worried about exposing but take a detailed look yourself.

Like @wkozyra95 said, the aws-exports.js is part of the js bundle after the app is built. As a result, it can also be replaced via an OTA update (eas update or expo updates). We updated our app via eas update and accidentally pointed our prod users to our dev backend for a short period of time so heads up @AllanBengco.

@AllanBengco
Copy link

@diegoconcha If you are using default git workflow (you don't have requireCommit: true in eas.json) then you can add .easignore file
Note that if easignore is present, gitingore files are not respected(even in subdirectories) and there can only be one .easignore and it has to be in the root of the repository

Thanks @wkozyra95 for your reply. The challenge with this approach is now we have to keep two ignore files up-to-date (.gitignore and .easignore). This approach is definitely an improvement over the base64 encoded string and eas pre-install step discussed above but it would probably be easier for most teams if expo added a .easincludes file where we can include important cloud configuration files like the aws-exports.js in our case. I hope you all consider adding this in the near future.

Hi @diegoconcha or @everyone here! I am currently on the process of eas build-ing an app, and I was wondering whether to use the base64 route or this .easignore. I am leaning towards the latter, but I am worried about inadvertently exposing my aws-exports.js to prying eyes. What are your thoughts about this?

Hey @AllanBengco we went the .easignore route. Ours is a copy of our .gitignore without the aws-exports.js so that the aws-exports.js is included in the build. This file only has routes and high level config of our backend so mostly stuff that's already easy to figure out by analyzing network traffic on the device or using our app. Essentially nothing we're worried about exposing but take a detailed look yourself.

Like @wkozyra95 said, the aws-exports.js is part of the js bundle after the app is built. As a result, it can also be replaced via an OTA update (eas update or expo updates). We updated our app via eas update and accidentally pointed our prod users to our dev backend for a short period of time so heads up @AllanBengco.

Thank you @diegoconcha for your inputs!

I experimented with the base64 route, and was able to build my app successfully. Based on your comment, I realized that the one good thing about encoding aws-exports is that I do not have to always remember to strictly follow git checkout prod and amplify env checkout prod, before eas build. Even if I accidentally build what is in the dev branch, the encoded aws-exports remains unchanged in EAS Secrets, reducing the likelihood of accidents similar to what you described.

@diegoconcha
Copy link

diegoconcha commented Mar 16, 2022

@diegoconcha If you are using default git workflow (you don't have requireCommit: true in eas.json) then you can add .easignore file
Note that if easignore is present, gitingore files are not respected(even in subdirectories) and there can only be one .easignore and it has to be in the root of the repository

Thanks @wkozyra95 for your reply. The challenge with this approach is now we have to keep two ignore files up-to-date (.gitignore and .easignore). This approach is definitely an improvement over the base64 encoded string and eas pre-install step discussed above but it would probably be easier for most teams if expo added a .easincludes file where we can include important cloud configuration files like the aws-exports.js in our case. I hope you all consider adding this in the near future.

Hi @diegoconcha or @everyone here! I am currently on the process of eas build-ing an app, and I was wondering whether to use the base64 route or this .easignore. I am leaning towards the latter, but I am worried about inadvertently exposing my aws-exports.js to prying eyes. What are your thoughts about this?

Hey @AllanBengco we went the .easignore route. Ours is a copy of our .gitignore without the aws-exports.js so that the aws-exports.js is included in the build. This file only has routes and high level config of our backend so mostly stuff that's already easy to figure out by analyzing network traffic on the device or using our app. Essentially nothing we're worried about exposing but take a detailed look yourself.
Like @wkozyra95 said, the aws-exports.js is part of the js bundle after the app is built. As a result, it can also be replaced via an OTA update (eas update or expo updates). We updated our app via eas update and accidentally pointed our prod users to our dev backend for a short period of time so heads up @AllanBengco.

Thank you @diegoconcha for your inputs!

I experimented with the base64 route, and was able to build my app successfully. Based on your comment, I realized that the one good thing about encoding aws-exports is that I do not have to always remember to strictly follow git checkout prod and amplify env checkout prod, before eas build. Even if I accidentally build what is in the dev branch, the encoded aws-exports remains unchanged in EAS Secrets, reducing the likelihood of accidents similar to what you described.

@AllanBengco when the app is built, the base64 method creates the aws-exports.js file so you still have the same issue if you do an expo or eas update since the file is still created and part of the js bundle. EAS Secrets is really only protecting build-time secrets and it isn't used at run-time which is when the aws-exports.js is used and where it can be modified by doing an over-the-air update. By using the base64 + EAS Secrets approach now you have to remember to update the secret if anything on your amplify backend changes like the userpool id. So you're adding an extra step but don't have the protection you think you have.

@AllanBengco
Copy link

@diegoconcha If you are using default git workflow (you don't have requireCommit: true in eas.json) then you can add .easignore file
Note that if easignore is present, gitingore files are not respected(even in subdirectories) and there can only be one .easignore and it has to be in the root of the repository

Thanks @wkozyra95 for your reply. The challenge with this approach is now we have to keep two ignore files up-to-date (.gitignore and .easignore). This approach is definitely an improvement over the base64 encoded string and eas pre-install step discussed above but it would probably be easier for most teams if expo added a .easincludes file where we can include important cloud configuration files like the aws-exports.js in our case. I hope you all consider adding this in the near future.

Hi @diegoconcha or @everyone here! I am currently on the process of eas build-ing an app, and I was wondering whether to use the base64 route or this .easignore. I am leaning towards the latter, but I am worried about inadvertently exposing my aws-exports.js to prying eyes. What are your thoughts about this?

Hey @AllanBengco we went the .easignore route. Ours is a copy of our .gitignore without the aws-exports.js so that the aws-exports.js is included in the build. This file only has routes and high level config of our backend so mostly stuff that's already easy to figure out by analyzing network traffic on the device or using our app. Essentially nothing we're worried about exposing but take a detailed look yourself.
Like @wkozyra95 said, the aws-exports.js is part of the js bundle after the app is built. As a result, it can also be replaced via an OTA update (eas update or expo updates). We updated our app via eas update and accidentally pointed our prod users to our dev backend for a short period of time so heads up @AllanBengco.

Thank you @diegoconcha for your inputs!
I experimented with the base64 route, and was able to build my app successfully. Based on your comment, I realized that the one good thing about encoding aws-exports is that I do not have to always remember to strictly follow git checkout prod and amplify env checkout prod, before eas build. Even if I accidentally build what is in the dev branch, the encoded aws-exports remains unchanged in EAS Secrets, reducing the likelihood of accidents similar to what you described.

@AllanBengco when the app is built the base64 method creates the file so you still have the same issue if you do an expo or eas update since the file is still created. Secrets is really only protecting build-time secrets it doesn't get used at run-time which is when the aws-exports.js is used and where it can be modified by doing an over-the-air update.

What I did was to manually create the base64 file and save this in Secrets. Then, add a pre-build script so that what is stored in Secrets is decoded and saved as aws-exports.js

  1. $base64 aws-exports.js
  2. Copy the output
  3. In Expo.dev, add AWS_EXPORTS to Secrets and paste the value from the output
  4. Add "eas-build-pre-install": "echo $AWS_EXPORTS | base64 --decode > ./src/aws-exports.js" to package.json scripts.

I was under the impression that this would basically decode what is already in the Secrets and save it as aws-exports.js for building. I will experiment on this later and try to purposely use dev environment, then build.

@diegoconcha
Copy link

@diegoconcha If you are using default git workflow (you don't have requireCommit: true in eas.json) then you can add .easignore file
Note that if easignore is present, gitingore files are not respected(even in subdirectories) and there can only be one .easignore and it has to be in the root of the repository

Thanks @wkozyra95 for your reply. The challenge with this approach is now we have to keep two ignore files up-to-date (.gitignore and .easignore). This approach is definitely an improvement over the base64 encoded string and eas pre-install step discussed above but it would probably be easier for most teams if expo added a .easincludes file where we can include important cloud configuration files like the aws-exports.js in our case. I hope you all consider adding this in the near future.

Hi @diegoconcha or @everyone here! I am currently on the process of eas build-ing an app, and I was wondering whether to use the base64 route or this .easignore. I am leaning towards the latter, but I am worried about inadvertently exposing my aws-exports.js to prying eyes. What are your thoughts about this?

Hey @AllanBengco we went the .easignore route. Ours is a copy of our .gitignore without the aws-exports.js so that the aws-exports.js is included in the build. This file only has routes and high level config of our backend so mostly stuff that's already easy to figure out by analyzing network traffic on the device or using our app. Essentially nothing we're worried about exposing but take a detailed look yourself.
Like @wkozyra95 said, the aws-exports.js is part of the js bundle after the app is built. As a result, it can also be replaced via an OTA update (eas update or expo updates). We updated our app via eas update and accidentally pointed our prod users to our dev backend for a short period of time so heads up @AllanBengco.

Thank you @diegoconcha for your inputs!
I experimented with the base64 route, and was able to build my app successfully. Based on your comment, I realized that the one good thing about encoding aws-exports is that I do not have to always remember to strictly follow git checkout prod and amplify env checkout prod, before eas build. Even if I accidentally build what is in the dev branch, the encoded aws-exports remains unchanged in EAS Secrets, reducing the likelihood of accidents similar to what you described.

@AllanBengco when the app is built the base64 method creates the file so you still have the same issue if you do an expo or eas update since the file is still created. Secrets is really only protecting build-time secrets it doesn't get used at run-time which is when the aws-exports.js is used and where it can be modified by doing an over-the-air update.

What I did was to manually create the base64 file and save this in Secrets. Then, add a pre-build script so that what is stored in Secrets is decoded and saved as aws-exports.js

  1. $base64 aws-exports.js
  2. Copy the output
  3. In Expo.dev, add AWS_EXPORTS to Secrets and paste the value from the output
  4. Add "eas-build-pre-install": "echo $AWS_EXPORTS | base64 --decode > ./src/aws-exports.js" to package.json scripts.

I was under the impression that this would basically decode what is already in the Secrets and save it as aws-exports.js for building. I will experiment on this later and try to purposely use dev environment, then build.

You're correct but you are missing my point. As part of the build process, the aws-exports.js gets created and is present in the built bundle. More precisely it lives in the JS bundle which can be overwritten by an OTA update (this is the magic of OTA updates replacing the JS bundle). If you don't do or plan to do OTA updates then you're fine but most people using expo do OTA updates to get hot fixes out quickly without waiting for app store approval in which case you can accidentally overwrite the aws-exports.js that was built from the secret with whatever you have locally when you create the OTA update.

@zaniluca
Copy link

Hi guys,

You don't need to commit the gitignored files to the repo.

Here's a workaround (assuming you want your build to have access to google-service.json):

  • Convert the secret file to a base64-encoded string:
    $ base64 google-services.json
  • Copy the output of the command and set an EAS secret with eas secret:create (e.g. GOOGLE_SERVICES_BASE64)
  • Use an EAS Build hook (https://docs.expo.io/build-reference/how-tos/#eas-build-specific-npm-hooks) to restore the file:
    In package.json:
    "eas-build-pre-install": "echo $GOOGLE_SERVICES_BASE64 | base64 --decode > /path/to/google-services.json"

I Don't know if this is expected behavior but if I have my app.json file like this, expecting google services files in the root directory, for some reason EAS doesn't care and keeps searching them in the ios / android subdirectories.

app.json

{
  "expo": {
    "name": "Ping for Gitlab",
    "owner": "zaniluca",
    "slug": "ping4gitlab",
    "version": "1.0.0",
    "orientation": "portrait",
    "icon": "./assets/icon.png",
    "splash": {
      "image": "./assets/splash.png",
      "resizeMode": "contain",
      "backgroundColor": "#ffffff"
    },
    "updates": {
      "fallbackToCacheTimeout": 0
    },
    "assetBundlePatterns": ["**/*"],
    "ios": {
      "bundleIdentifier": "con.zaniluca.ping4gitlab",
      "googleServicesFile": "./GoogleService-Info.plist",
      "supportsTablet": false
    },
    "android": {
      "googleServicesFile": "./google-services.json",
      "package": "con.zaniluca.ping4gitlab",
      "adaptiveIcon": {
        "foregroundImage": "./assets/adaptive-icon.png",
        "backgroundColor": "#FFFFFF"
      }
    },
    "plugins": ["@react-native-firebase/app"]
  }
}

EAS Error message when building ios

› Copying   ios/PingforGitlab/Supporting/Expo.plist ➜ ./Expo.plist
› Compiling PingforGitlab » SplashScreen.storyboard
› Copying   ios/PingforGitlab/GoogleService-Info.plist ➜ ./GoogleService-Info.plist

❌  error: Build input file cannot be found: '/Users/expo/workingdir/build/ios/PingforGitlab/GoogleService-Info.plist' (in target 'PingforGitlab' from project 'PingforGitlab')

The solution I adopted is this:

echo $GOOGLE_SERVICES_ANDROID_BASE64 | base64 --decode > ./android/app/google-services.json && echo $GOOGLE_SERVICES_IOS_BASE64 | base64 --decode > ios/PingforGitlab/GoogleService-Info.plist

Is there anything that I'm doing wrong

@wkozyra95
Copy link
Contributor

@zaniluca app.json values that configure native code are ignored if you are ejected. I checked your last few builds and they are all bare workflow, if ejecting was not intentional you can just delete or gitiingore android and ios directories

@zaniluca
Copy link

@zaniluca app.json values that configure native code are ignored if you are ejected. I checked your last few builds and they are all bare workflow, if ejecting was not intentional you can just delete or gitiingore android and ios directories

Oh really? I'm using a custom development client, I didn't know it was the same as ejecting. Thanks for pointing it out😅

@wkozyra95
Copy link
Contributor

I'm using a custom development client, I didn't know it was the same as ejecting.

It's not the same, you can use a custom dev client without ejecting. Most likely you ejected by running expo run:ios/android or expo prebuild

@zaniluca
Copy link

I'm using a custom development client, I didn't know it was the same as ejecting.

It's not the same, you can use a custom dev client without ejecting. Most likely you ejected by running expo run:ios/android or expo prebuild

Yea I had to run expo prebuild as stated in the react-native-firebase docs thanks

@ShepSims
Copy link

I've tried following both versions of how to upload the secrets and am still getting errors, and am wondering if anyone has succeeded in fixing them, or could provide some extra help.

When trying the .easignore version I created a base level .easignore and set its contents to the same as my .gitignore, but with the aws-exports and google services files negated as below

!aws-exports.js
!google-services.json

This didn't fix the original issue or change anything at all in the built, and gave the same results as not doing this, getting

File specified via "android.googleServicesFile" field in your app.json is not checked in to your repository and won't be uploaded to the builder.
Use EAS Secret to pass all values that you don't want to include in your version control. Learn more: https://docs.expo.dev/build-reference/variables/#using-secrets-in-environment-variables
If you are using that file for compatibility with the classic build service (expo build) you can silence this warning by setting your build profile's env.GOOGLE_SERVICES_FILE in eas.json to any non-empty string.

then, during the gradlew and fastline build processes in android and iOS respectively

❌ Metro encountered an error:
Unable to resolve module ./src/aws-exports from /Users/expo/workingdir/build/index.js:

None of these files exist:
  * src/aws-exports(.native|.ios.ts|.native.ts|.ts|.ios.tsx|.native.tsx|.tsx|.ios.js|.native.js|.js|.ios.jsx|.native.jsx|.jsx|.ios.json|.native.json|.json)

So I moved onto the secrets route

After base64'ing my aws-exports and google-services.json, creating eas secrets from them named GOOGLE_SERVICES and AWS_EXPORTS with that output via eas secret:create, then adding the following pre-install script in package.json

"eas-build-pre-install": "echo $GOOGLE_SERVICES | base64 --decode > ./google-services.json && echo $AWS_EXPORTS | base64 --decode > ./src/aws-exports.json"

I am now getting this error in both the Xcode Logs for iOS, and in the gradlew logs for Android

error src/aws-exports.json: Unexpected token: keyword (const) in file src/aws-exports.json at 5:0.

Seems to me like it now recognizes that the files exist, but isn't able to read from them and I am unsure as to why. Obviously const is a valid kwarg in js, and the first thing appearing in aws-exports.

I would love any direction on how to fix if anyone has suggestions, thanks in advance!

@danieldanielecki
Copy link

Lots of comments, it'd be great to have a mini tutorial how to handle this situation in the Expo's docs.

@wkozyra95
Copy link
Contributor

Seems to me like it now recognizes that the files exist, but isn't able to read from them and I am unsure as to why. Obviously const is a valid kwarg in js, and the first thing appearing in aws-exports.

@ShepSims in js yes, but you created json file

Lots of comments, it'd be great to have a mini tutorial how to handle this situation in the Expo's docs.

@danieldanielecki It works the same as in every other CI service

@carlwillimott
Copy link

Not completely related, but in case this helps anyone who is struggling with multiple amplify envs I have been doing this:

"eas-build-pre-install": "node scripts/pre-install.js"

Which runs the following node script:

const fs = require("fs");

const buildProfile = process.env.EAS_BUILD_PROFILE;
const configProd = process.env.AWS_EXPORTS;
const configDevelop = process.env.AWS_EXPORTS_DEVELOP;

const config = buildProfile === "production" ? configProd : configDevelop;

const decoded = Buffer.from(config, "base64").toString();

fs.writeFileSync("./src/aws-exports.js", decoded);

In summary, you still have to update the secrets as your backend changes but at least you can build for multiple envs as required.

For referenece - I was initially running the following script - but had issues with it not working for Play store builds (it works fine for iOS), probably not escaping some variable or something?

"eas-build-pre-install": "[ $EAS_BUILD_PROFILE == \"production\" ] && config=\"$AWS_EXPORTS\" || config=\"$AWS_EXPORTS_DEVELOP\"; echo $config | base64 -d > ./src/aws-exports.js;"

@aaly00
Copy link

aaly00 commented Jun 2, 2022

This should probably be upstreamed in amplify react native repo

@erquhart
Copy link

erquhart commented Jun 10, 2022

I have a related case - I use tailwind-rn for styles, so I constantly have unexpected changes to tailwind.css and tailwind.json in my commits, which results in merge conflicts with other PRs. Ignoring them and generating at build time works, but then eas also ignores them. So I started generating .easignore, too.

cc/ @diegoconcha as you mentioned having to keep two files up to date.

tl;dr: generate your .easignore from your .gitignore at build time.

Which (I think) is the only time you need it.

.gitignore:

node_modules/
.expo/
dist/

# ignore .easignore, too ✨
.easignore

### EASINCLUDE! ###
### BELOW THIS LINE WILL NOT BE IGNORED BY EAS ###

tailwind.css
tailwind.json

generate-easignore.js

const fs = require('fs')
const gitignore = fs.readFileSync('./.gitignore', 'utf8')
const easignore = gitignore.split('### EASINCLUDE! ###')[0]
fs.writeFileSync('./.easignore', easignore)

package.json

{
  "scripts": {
    "build": "node ./generate-easignore.js && eas build"
  }
}

This will output a .easignore that includes everything in .gitignore except the EASINCLUDE! line and everything below it. Use whatever you want for the separator string, I chose something that seemed programmatic so no one touches it unwittingly. Run it before you run eas build, probably in an npm script.

@VictorioMolina
Copy link

In my project, I have decided to include .psd, .ai and mockups inside my assets folder, just to include all the extra files in my git’s monorepo.

It has no sense to include .psd, .ai, or assets that are not displayed in the frontend, inside the native build.

If I include all the relative paths to the unused assets in my .easignore file… Will those files be included by EAS build?

———————-

Also, I have seen that in app.json we can include a list of glob patterns for assets (assetBundlePatterns). What’s the purpose for that field if we can ignore assets using .easignore?

@wkozyra95
Copy link
Contributor

@VictorioMolina .easignore if present replaces .gitignore If you want to upload sth that is not committed or stop from upload sth that is committed you can use that file https://github.com/expo/fyi/blob/main/eas-build-archive.md

assetBundlePatterns defines what assets are bundled inside the app for classic builds and it's not doing anything for eas build.
https://docs.expo.dev/guides/offline-support/#eas-build

@seemavora
Copy link

The following stackoverflow answer helped me resolve the issue: https://stackoverflow.com/questions/70906207/eas-build-fails-unable-to-resolve-module-aws-exports.

@WillSmithTE
Copy link

The build hook links have been updated

https://docs.expo.dev/build-reference/npm-hooks/

@WillSmithTE
Copy link

Surely the better solution these days is using eas file secrets

https://docs.expo.dev/build-reference/variables/

e.g. add secret with name ANDROID_GOOGLE_SERVICES_FILE_PATH, then in app.config.js/ts

android: {
    googleServicesFile: process.env.ANDROID_GOOGLE_SERVICES_FILE_PATH,
}

@DomGarza
Copy link

I'm facing this right now.

Just change the file from aws-exports.js to aws-exports.tsx and it will build

It's okay if they are in the JS bundle if you're using AWS authenticator with cognito because it only allows authenticated users to hit the apis. Just make your storage is set for only signed in users to upload, edit and delete

@katayama8000
Copy link

katayama8000 commented Jul 6, 2024

eas secret:create --scope project --name GOOGLE_SERVICES_JSON --type file --value ./path/to/google-services.json
✔ Created a new secret GOOGLE_SERVICES_JSON on project @user/myproject.
export default {
  android: {
    googleServicesFile: process.env.GOOGLE_SERVICES_JSON,
  },
};

https://docs.expo.dev/build-reference/variables/#how-to-upload-a-secret-file-and-use-it-in-my-app-config

@LuizCristino
Copy link

I gave up and just commited to the repo. This "service" never worked

@odeke
Copy link

odeke commented Aug 5, 2024

I used the eas secrets, but I only had app.json config file. So I manually had to create a app.config.js file. And then painstakingly, export all its variables in a js format from the json format, and was able to run the build after that. I did not delete the app.json file though.

For example:
app.json
{ "expo": { "name": "MyApp", "slug": "MyApp", "version": "1.1.4",

The new app.config.js
export default { expo: { name: "MyApp", slug: "MyApp", version: "1.1.4",

@anhtuan219
Copy link

anhtuan219 commented Aug 30, 2024

Here's what I'm using

For cloud build (eas build), follow this guide in expo docs. Upload google-services.json to eas secret to be used by cloud build

image

For local build (eas build --local, expo run:android), before running local build, export path file google-services.json to environment variables, that variable will be used for process.env.GOOGLE_SERVICES_JSON instead of eas secret

export GOOGLE_SERVICES_JSON="./google-services.json" && npx expo prebuild --platform android --clean && npx expo run:android

@melyux
Copy link

melyux commented Oct 7, 2024

@anhtuan219 This works well for expo run:ios, but eas build --local doesn't work that way; it won't have access to the path you give it because it won't copy the gitignored ./google-services.json file over to the local EAS Build sandbox in the first place. Is there some other way to get eas build --local to work here?

Another casualty of #2392

@anhtuan219
Copy link

anhtuan219 commented Oct 7, 2024

@melyux Yeah, after a while I noticed that this way doesn't work for eas build --local. Here's the update:
As per the expo docs, eas can't be used with local build, and expo recommends setting these secrets in environment variables instead
image

That means we can set it like this right?

export GOOGLE_SERVICES_JSON="./google-services.json" && eas build --local --platform android

or like this (absolute path version)?

export GOOGLE_SERVICES_JSON="~/google-services.json" && eas build --local --platform android

But sadly, none of those works, it always fails at the step Prebuild. When checking this carefully, I discovered that the native project (result of the prebuild step) isn't created in the project's root directory. Instead, eas created it in another directory.
And the path to the google-services.json file that is exported to the environment variable? That path must be relative to the directory where the prebuild happens, that's why eas can't find the google-services.json file (because the environment variable's value is the path relative to the project's root directory or absolute path) and yields the error that can't find the file.
In linux, looking at the log, I found the directory where prebuild step happens is /tmp/my_name/eas-build-local-nodejs/random_id/build.

So, to fix this, we need to export the path that is relative to the directory where the prebuilds happen. You can use the parent directory selector (..) repeatedly until you reach the root directory (/) and from that, append the path to the project's root directory
For example: My path to google-services.json is ~/pet_project/awesome_project/google-services.json (~ is /home/my_name btw)
-> The path to exported is: ../../../../../home/my_name/pet_project/awesome_project/google-services.json
You can think of this like

/tmp/my_name/eas-build-local-nodejs/random_id/build/../../../../../home/my_name/pet_project/awesome_project/google-services.json

equal to
~/pet_project/awesome_project/google-services.json

With those changes, my prebuild was successful, and my eas local build works. Here's the complete command that I'm using when running eas build local for android on linux

export GOOGLE_SERVICES_JSON="../../../../../home/my_name/pet_project/awesome_project/google-services.json" && eas build --local --platform android

And now you want to know exactly the directory where the prebuil step happens, after fixing this issue, I found that eas does log it to the console in the first steps (specifically step [SETUP_WORKINGDIR]). In my specific case, it's /tmp/my_name/eas-build-local-nodejs/random_id
-> The directory where the prebuil step happens is

directory_step_SETUP_WORKINGDIR/build

Hope this help!!

@melyux
Copy link

melyux commented Oct 8, 2024

@anhtuan219 I was able to get the files working with EAS Build --local without having to go through the directory structure! Using .easignore. Check it out

@toppsdown
Copy link

Does the google-services.json file even need to be gitignored?

The expo documentation says yes, but there are several posts on google groups and stack overflow that indicate that there's nothing sensitive in the file, and that it's included in the final build and can easily be extracted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests