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 --local doesn't work with google services files #1253

Closed
zaniluca opened this issue Aug 7, 2022 · 9 comments
Closed

eas build --local doesn't work with google services files #1253

zaniluca opened this issue Aug 7, 2022 · 9 comments

Comments

@zaniluca
Copy link

zaniluca commented Aug 7, 2022

Build/Submit details page URL

No response

Summary

When launching a build in a CI environment (or on a local machine, tested with macOS) with eas build --local and a package that requires a google services file (both google-services.json or GoogleService-Info.plist) to be used the build errors out when reading/parsing the file.

This can be a problem for packages like expo-firebase-core, expo-notifications and all the ones that require a google services file to be used.

Managed or bare?

Managed

Environment

npx expo-env-info
  expo-env-info 1.0.5 environment info:
    System:
      OS: macOS 12.3.1
      Shell: 5.8 - /bin/zsh
    Binaries:
      Node: 14.19.1 - ~/.nvm/versions/node/v14.19.1/bin/node
      Yarn: 1.22.17 - /opt/homebrew/bin/yarn
      npm: 6.14.16 - ~/.nvm/versions/node/v14.19.1/bin/npm
    Managers:
      CocoaPods: 1.11.3 - /opt/homebrew/bin/pod
    SDKs:
      iOS SDK:
        Platforms: DriverKit 21.4, iOS 15.5, macOS 12.3, tvOS 15.4, watchOS 8.5
    IDEs:
      Xcode: 13.4.1/13F100 - /usr/bin/xcodebuild
    npmPackages:
      expo: ~45.0.0 => 45.0.8 
      react: 17.0.2 => 17.0.2 
      react-dom: 17.0.2 => 17.0.2 
      react-native: 0.68.2 => 0.68.2 
      react-native-web: 0.17.7 => 0.17.7 
    npmGlobalPackages:
      eas-cli: 0.52.0
      expo-cli: 5.4.6
    Expo Workflow: managed
expo doctor
🎉 Didn't find any issues with the project!

Error output

Android Action Error
[RUN_GRADLEW] FAILURE: Build failed with an exception.
[RUN_GRADLEW] > Task :app:generateReleaseResValues
[RUN_GRADLEW] > Task :app:generateReleaseResources
[RUN_GRADLEW] > Task :app:processReleaseGoogleServices FAILED
[RUN_GRADLEW] Parsing json file: /tmp/runner/eas-build-local-nodejs/89c69241-1ba0-4a67-9fad-208fdbf53d66/build/android/app/google-services.json
[RUN_GRADLEW] Deprecated Gradle features were used in this build, making it incompatible with Gradle 8.0.
[RUN_GRADLEW] You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.
[RUN_GRADLEW] See https://docs.gradle.org/7.3.3/userguide/command_line_interface.html#sec:command_line_warnings
[RUN_GRADLEW] Execution optimizations have been disabled for 1 invalid unit(s) of work during this build to ensure correctness.
[RUN_GRADLEW] Please consult deprecation warnings for more details.
[RUN_GRADLEW] 36 actionable tasks: 36 executed
[RUN_GRADLEW] * What went wrong:
[RUN_GRADLEW] Execution failed for task ':app:processReleaseGoogleServices'.
[RUN_GRADLEW] > Malformed root json
[RUN_GRADLEW] * Try:
[RUN_GRADLEW] > Run with --stacktrace option to get the stack trace.
[RUN_GRADLEW] > Run with --info or --debug option to get more log output.
[RUN_GRADLEW] > Run with --scan to get full insights.
[RUN_GRADLEW] * Get more help at https://help.gradle.org/
[RUN_GRADLEW] BUILD FAILED in 3m 30s
[RUN_GRADLEW] Error: Gradle build failed with unknown error. Please see logs for the "Run gradlew" phase.
iOS Action Error
[PREBUILD] ✖ Config sync failed
[PREBUILD] [13:13:07] [ios.infoPlist]: withIosInfoPlistBaseMod: GoogleService-Info.plist is empty
[PREBUILD] 
Error: bash exited with non-zero code: 1
    at ChildProcess.completionListener (/Users/runner/.npm/_npx/12046/lib/node_modules/eas-cli-local-build-plugin/node_modules/@expo/spawn-async/build/spawnAsync.js:41:23)
    at Object.onceWrapper (events.js:520:26)
    at ChildProcess.emit (events.js:400:28)
    at maybeClose (internal/child_process.js:1088:16)
    at Socket.<anonymous> (internal/child_process.js:446:11)
[CLEAN_UP_CREDENTIALS] Destroying keychain - /var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/turtle-v2-12d7aadd-d039-44fd-afd7-c33b1a3c2b46.keychain
    at Socket.emit (events.js:400:28)
    at Pipe.<anonymous> (net.js:686:12)
    ...
    at spawnAsync (/Users/runner/.npm/_npx/12046/lib/node_modules/eas-cli-local-build-plugin/node_modules/@expo/spawn-async/build/spawnAsync.js:7:23)
    at spawn (/Users/runner/.npm/_npx/12046/lib/node_modules/eas-cli-local-build-plugin/node_modules/@expo/turtle-spawn/dist/index.js:17:47)
    at BuildContext.runExpoCliCommandAsync [as runExpoCliCommand] (/Users/runner/.npm/_npx/12046/lib/node_modules/eas-cli-local-build-plugin/dist/expoCli.js:14:39)
    at prebuildAsync (/Users/runner/.npm/_npx/12046/lib/node_modules/eas-cli-local-build-plugin/node_modules/@expo/build-tools/dist/utils/prebuild.js:18:15)
    at /Users/runner/.npm/_npx/12046/lib/node_modules/eas-cli-local-build-plugin/node_modules/@expo/build-tools/dist/builders/ios.js:33:52
    at BuildContext.runBuildPhase (/Users/runner/.npm/_npx/12046/lib/node_modules/eas-cli-local-build-plugin/node_modules/@expo/build-tools/dist/context.js:49:34)
    at Object.iosBuilder (/Users/runner/.npm/_npx/12046/lib/node_modules/eas-cli-local-build-plugin/node_modules/@expo/build-tools/dist/builders/ios.js:29:23)
    at async buildIosAsync (/Users/runner/.npm/_npx/12046/lib/node_modules/eas-cli-local-build-plugin/dist/ios.js:49:27)
    at async buildAsync (/Users/runner/.npm/_npx/12046/lib/node_modules/eas-cli-local-build-plugin/dist/build.js:28:32)
    at async main (/Users/runner/.npm/_npx/12046/lib/node_modules/eas-cli-local-build-plugin/dist/main.js:16:9)
[CLEAN_UP_CREDENTIALS] Removing provisioning profile

Build failed
bash exited with non-zero code: 1
    Error: npx exited with non-zero code: 1
Error: Process completed with exit code 1.
Local iOS Error
[PREBUILD] - Config syncing
[PREBUILD] ✖ Config sync failed
[PREBUILD] [15:24:01] [ios.infoPlist]: withIosInfoPlistBaseMod: GoogleService-Info.plist is empty
[PREBUILD] 
Error: bash exited with non-zero code: 1
    at ChildProcess.completionListener (/Users/luca/.npm/_npx/4303fabdaa4f873a/node_modules/@expo/spawn-async/build/spawnAsync.js:41:23)
    at Object.onceWrapper (node:events:642:26)
    at ChildProcess.emit (node:events:527:28)
    at maybeClose (node:internal/child_process:1092:16)
    at Process.ChildProcess._handle.onexit (node:internal/child_process:302:5)
    ...
    at spawnAsync (/Users/luca/.npm/_npx/4303fabdaa4f873a/node_modules/@expo/spawn-async/build/spawnAsync.js:7:23)
    at spawn (/Users/luca/.npm/_npx/4303fabdaa4f873a/node_modules/@expo/turtle-spawn/dist/index.js:17:47)
    at BuildContext.runExpoCliCommandAsync [as runExpoCliCommand] (/Users/luca/.npm/_npx/4303fabdaa4f873a/node_modules/eas-cli-local-build-plugin/dist/expoCli.js:14:39)
    at prebuildAsync (/Users/luca/.npm/_npx/4303fabdaa4f873a/node_modules/@expo/build-tools/dist/utils/prebuild.js:14:15)
    at /Users/luca/.npm/_npx/4303fabdaa4f873a/node_modules/@expo/build-tools/dist/builders/ios.js:33:52
    at BuildContext.runBuildPhase (/Users/luca/.npm/_npx/4303fabdaa4f873a/node_modules/@expo/build-tools/dist/context.js:48:34)
    at Object.iosBuilder (/Users/luca/.npm/_npx/4303fabdaa4f873a/node_modules/@expo/build-tools/dist/builders/ios.js:29:23)
    at async buildIosAsync (/Users/luca/.npm/_npx/4303fabdaa4f873a/node_modules/eas-cli-local-build-plugin/dist/ios.js:49:27)
    at async buildAsync (/Users/luca/.npm/_npx/4303fabdaa4f873a/node_modules/eas-cli-local-build-plugin/dist/build.js:28:32)
    at async main (/Users/luca/.npm/_npx/4303fabdaa4f873a/node_modules/eas-cli-local-build-plugin/dist/main.js:16:9)
[CLEAN_UP_CREDENTIALS] Destroying keychain - /var/folders/cv/q01lr7vn6vd10hy2y_m7744h0000gn/T/turtle-v2-caa1af61-ada8-4c51-b6ed-4e3b8403f41e.keychain
[CLEAN_UP_CREDENTIALS] Removing provisioning profile

Build failed
bash exited with non-zero code: 1

Reproducible demo or steps to reproduce from a blank project

I made an example project with SDK 45 and a GitHub action that installs the required packages for eas --local to work. This project was a standard expo init to which I added expo-firebase-core.

As for best practice, the google services files are provided via an eas-build-pre-install hook which parses the base64 content of an environment variable containing the encoded services files. Of course, when I run the local build on my MacBook they're in the path specified in app.json

The decoding strategy above is proven to be working in a cloud build here for android

The GitHub action has been taken from this project: https://github.com/byCedric/eas-gha

This is the example project: https://github.com/zaniluca/eas-local-build-google-services-error

And here if you visit this workflow run you can see the error thrown when building. both for an iOS and Android build

@zaniluca zaniluca added the needs review Issue is ready to be reviewed by a maintainer label Aug 7, 2022
@wkozyra95
Copy link
Contributor

secrets do not work with local builds, you will need to set GOOGLE_SERVICES_IOS_BASE64 and GOOGLE_SERVICES_ANDROID_BASE64 in your shell

@wkozyra95 wkozyra95 removed the needs review Issue is ready to be reviewed by a maintainer label Aug 8, 2022
@zaniluca
Copy link
Author

zaniluca commented Aug 8, 2022

secrets do not work with local builds, you will need to set GOOGLE_SERVICES_IOS_BASE64 and GOOGLE_SERVICES_ANDROID_BASE64 in your shell

@wkozyra95 But even with the files in my local directory (so that I don't have to do the decoding of GOOGLE_SERVICES_IOS_BASE64 and GOOGLE_SERVICES_ANDROID_BASE64 ), if I run eas build --local i get the same error

The error output I added in Local iOS Error is the result of building a local project with both services files in the directory they're supposed to be, or the build wouldn't even start because the cli would complain that i don' have the files specified in app.json

// app.json
{
  "expo": {
    ...
    "ios": {
      ...
      "googleServicesFile": "./GoogleService-Info.plist",
    },
    "android": {
      "googleServicesFile": "./google-services.json",
      ...
    },
  }
}

So I don't think its just a problem with the secrets not being processed by eas build --local

@wkozyra95
Copy link
Contributor

when running local builds the same rules apply as for cloud builds, gitignored files are not part of the build

@zaniluca
Copy link
Author

zaniluca commented Aug 8, 2022

when running local builds the same rules apply as for cloud builds, gitignored files are not part of the build

@wkozyra95 oh ok thank you! so if I want to make this work how can I do it? is there a way to make these files included by eas without committing them to git?

Also trying to build without having them ignored doesn't seem to work
Schermata 2022-08-08 alle 11 22 22

@wkozyra95
Copy link
Contributor

if I want to make this work how can I do it?

Just set those envs in the shell

Is there a way to make these files included by eas without committing them to git?

You can do it using .easignore file, but I don't recommend it https://github.com/expo/fyi/blob/main/eas-build-archive.md

Also trying to build without having them ignored doesn't seem to work

You probably still have that hook in package JSON that overrides the files. echo $GOOGLE_SERVICES_ANDROID_BASE64 | base64 --decode > ./google-services.json creates empty file if env is not set.

@zaniluca
Copy link
Author

zaniluca commented Aug 8, 2022

@wkozyra95 Thank you again! now this works great!

@zaniluca zaniluca closed this as completed Aug 8, 2022
@rgomezp
Copy link

rgomezp commented Feb 13, 2024

Hey Wojciech,
Rodrigo here. I'm trying to do the same as OP: do a local eas build and also leverage Expo secrets when doing a cloud build.

Setup

In my app.config.js I have:

export default {
   ...
   ios: {
      googleServicesFile: process.env.GOOGLE_SERVICES_PLIST,
   }
   ...
}

Which I have on Expo as a secret:

Screenshot 2024-02-13 at 3 51 44 PM

Question: can you please clarify the discrepancy of the value being a file path vs a file and how that differs between local and cloud builds?

Trying to run eas build --local

In my .env, I have:

export GOOGLE_SERVICES_PLIST="googleServices/GoogleService-Info.plist"

I can tell the local build picks that up from the .env because of the build error:

[PREBUILD] Error: [ios.xcodeproj]: withIosXcodeprojBaseMod: ENOENT: no such file or directory, copyfile '/private/var/folders/jy/kb50bcvs0_v3fdgnbrmyw7fr0000gn/T/eas-build-local-nodejs/831efb7c-ab59-405e-92ac-b798cc304a63/build/googleServices/GoogleService-Info.plist' -> '/private/var/folders/jy/kb50bcvs0_v3fdgnbrmyw7fr0000gn/T/eas-build-local-nodejs/831efb7c-ab59-405e-92ac-b798cc304a63/build/ios/MyApp/GoogleService-Info.plist'
[PREBUILD] Error: [ios.xcodeproj]: withIosXcodeprojBaseMod: ENOENT: no such file or directory, copyfile '/private/var/folders/jy/kb50bcvs0_v3fdgnbrmyw7fr0000gn/T/eas-build-local-nodejs/831efb7c-ab59-405e-92ac-b798cc304a63/build/googleServices/GoogleService-Info.plist' -> '/private/var/folders/jy/kb50bcvs0_v3fdgnbrmyw7fr0000gn/T/eas-build-local-nodejs/831efb7c-ab59-405e-92ac-b798cc304a63/build/ios/MyApp/GoogleService-Info.plist'
[PREBUILD]     at Object.copyFileSync (node:fs:2969:3)
[PREBUILD]     at setGoogleServicesFile (/private/var/folders/jy/kb50bcvs0_v3fdgnbrmyw7fr0000gn/T/eas-build-local-nodejs/831efb7c-ab59-405e-92ac-b798cc304a63/build/node_modules/@expo/config-plugins/build/ios/Google.js:127:17)

You can see that the error message includes the file path defined in the .env. However, it doesn't find the files because the root is not my project root (e.g. /private/var/folders/jy/kb50bcvs0_v3fdgnbrmyw7fr0000gn/T/eas-build-local-nodejs/be9be592-a40b-4057-a335-33b37af70ced/build).

If I remove it from the .env, I get a different error:

[PREBUILD] Error: [ios.xcodeproj]: withIosXcodeprojBaseMod: Path to GoogleService-Info.plist is not defined. Please specify the `expo.ios.googleServicesFile` field in app.json.
[PREBUILD] Error: [ios.xcodeproj]: withIosXcodeprojBaseMod: Path to GoogleService-Info.plist is not defined. Please specify the `expo.ios.googleServicesFile` field in app.json.

So, I tried the following:

GOOGLE_SERVICES_PLIST=$(base64 -i googleServices/GoogleService-Info.plist)

But that had no effect and I still got that last error.

Summary

There are three pieces here that need to fit together:

  1. Local builds don't use cloud secrets so we have to rely on local secrets (i.e. .env)
  2. The cloud secret is a file, while the local secret is a path
  3. The local build picks up the file path in .env but there is nothing in that because it appears to have a different root

Thanks Wojciech


Solution

Edit: It looks like setting the GOOGLE_SERVICES_PLIST to the absolute path does the trick.

e.g:

export GOOGLE_SERVICES_JSON="/Users/rodrigo/Documents/MyApp/googleServices/google-services.json"
export GOOGLE_SERVICES_PLIST="/Users/rodrigo/Documents/MyApp/googleServices/GoogleService-Info.plist"

Not sure whether the base64 string is even needed here, although my environment might be slightly different than OP's.

Edit 2: this doesn't fully solve my problem though because I need this to run in Github Actions. Ideally I would store the file as a base64 encoded string as a secret on Github, but that doesn't appear to work, as mentioned above.

Any suggestions?

Edit 3: Disregard. I got it working. The answer was staring me in the face, but there are many moving pieces here. I'll leave this comment as a bread trail for anyone who encounters a similar issue.

I may put together a guide for this.

Edit 4: I actually did put a guide together for this

@anhtuan219
Copy link

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

@anhtuan219
Copy link

Updated: the path of google-services.json for expo run:android and expo run:ios is different from the path of google-services.json for eas build --local
Detail here

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

4 participants