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

feat(continuous-deploy-fingerprint): Add optional environment input for EAS updates #316

Closed
wants to merge 7 commits into from

Conversation

tharakadesilva
Copy link
Contributor

@tharakadesilva
Copy link
Contributor Author

Hi @wschurman,

I'd appreciate your review on this PR. A couple of quick notes:

  1. The failing CI job appears unrelated to my changes.
  2. I'm still learning the approval request process - could you point me to any documentation or guidelines I should follow?

Thanks for your help!

@wschurman wschurman self-requested a review December 6, 2024 00:49
@wschurman
Copy link
Member

The failing CI job appears unrelated to my changes.

Yep, this happens for external contributions. No worries.

I'm still learning the approval request process - could you point me to any documentation or guidelines I should follow?

I added myself as a reviewer. I should have time to review in the next few days. I think we need to ensure that both this and the call here both use the same env variables since they could be in the app.json. And then we also probably need a way to guarantee that they are the same ones as the eas build profile uses?

I'll put some more thought into this in the next couple days.

@tharakadesilva
Copy link
Contributor Author

tharakadesilva commented Dec 6, 2024

I think we need to ensure that both this and the call here both use the same env variables since they could be in the app.json.

Ah, this is something that I missed, thanks for bringing this up!

I actually haven't referenced any variables in app.json in my setup (except SENTRY_TOKEN, but that is used at build time), which is probably why it worked in my use case that I described here.

This brings up an interesting question though: Should the fingerprint change when a JS bundle env var changes? For variables specified in app.json (like SENTRY_TOKEN), aren't these only used during build time rather than update publish time?

And then we also probably need a way to guarantee that they are the same ones as the eas build profile uses?

Based on the documentation, this seems to be already handled. The environment variables are made available based on the active profile, so no additional work should be needed on our end.

The main issue was with updates. With updates:

When the --environment flag is not provided, eas update will use the .env files present in your project directory for the update job and won't use the environment variables set on the EAS servers.

This explains why in my Supabase implementation, while the environment variables were available during build time, they weren't accessible via process.env during update publishing since they weren't present during that phase.

I'll put some more thought into this in the next couple days.

I really appreciate your feedback and time on this! And please excuse any misunderstandings on my part – I'm still quite new to this ecosystem.

Copy link
Member

This brings up an interesting question though: Should the fingerprint change when a JS bundle env var changes? For variables specified in app.json (like SENTRY_TOKEN), aren't these only used during build time rather than update publish time?

The fingerprint runtime version is used to declare precise compatibility between builds and updates, so if something changes the build runtime version the only way to guarantee compatibility is if the update runtime version is also changed. Anything that changes the build changes the fingerprint by default, though all users have the ability to exclude things from fingerprint if they wish via the provided exclusion mechanisms to set up custom rules for excluding certain changes from changing the fingerprint.

And then we also probably need a way to guarantee that they are the same ones as the eas build profile uses?
Based on the documentation, this seems to be already handled. The environment variables are made available based on the active profile, so no additional work should be needed on our end.

Sorry, I should have been more precise. I more meant guarantee/require that the "environment" string provided here matches the "environment" string in the eas.json profile. This way, if the build profile specifies an environment we can throw a warning if the "environment" flag you add isn't provided.

Copy link
Member

Asking internally how we recommend fixing this for EAS environment variables, will get back to you in a few days.

@wschurman
Copy link
Member

@tharakadesilva - I added some code that should theoretically load environment variables for execution of the npx expo config call and the npx expo-updates fingerprint:generate call. I haven't had time to test it yet though.

@tharakadesilva
Copy link
Contributor Author

tharakadesilva commented Dec 14, 2024

Thanks @wschurman!! Let me run a few tests.

@tharakadesilva
Copy link
Contributor Author

tharakadesilva commented Dec 15, 2024

Hey Will, these are the changes that I did so far:

  1. 052de8a - eas env:exec preview npx expo config --json --type public broke, so I had to wrap the sub command in quotes like this: eas env:exec preview "npx expo config --json --type public".
  2. f50f1e7 - Control silent mode based on debug mode.

Now, I am stuck on:

[stderr] bash: line 1: npx expo config --json --type public: command not found
❌ "npx expo config --json --type public" failed
bash -c "npx expo config --json --type public" exited with non-zero code: 127
    Error: env:exec command failed.

From an initial glance, it looks like the npx command is not found when we spawn a process with bash -c. I tried some things using which and realpath instead of npx, but didn't have any luck with them either.

I also tried a ls -la on the action and through eas env:exec. These are the results:

  • Without env:exec: lrwxrwxrwx 1 root root 38 Dec 11 14:05 /usr/local/bin/npx -> ../lib/node_modules/npm/bin/npx-cli.js\n
  • With env:exec: ls: command not found

For sanity, since the npx symlink is under a user local bin folder, I did a whoami and this is the result:

  • Without env:exec: runner
  • With env:exec: Environment variables with visibility "Plain text" and "Sensitive" loaded from the "preview" environment on EAS: BUILD_VAR, EXPO_PUBLIC_UPDATE_VAR.\n' + '\n' + 'Running command: "whoami"\n' + '[stdout] runner\n

The user hadn't changed, but the tools were no longer being found for some reason. This might be a sandbox feature of Github actions (or am I in a completely different env altogether...?).

I will keep playing around with this later today. Sharing my progress in case you might know of a quick solution for this.

@tharakadesilva
Copy link
Contributor Author

tharakadesilva commented Dec 15, 2024

After reading this article I tried eval here instead of bash -c here, but ended up with:

Environment variables with visibility "Plain text" and "Sensitive" loaded from the "preview" environment on EAS: BUILD_VAR, EXPO_PUBLIC_UPDATE_VAR.
Running command: "npx expo config --json --type public"
❌ "npx expo config --json --type public" failed
spawn eval ENOENT
    Error: env:exec command failed.

Another potential approach to this seems to be eas env:pull. However, that doesn't solve this exact problem.


Didn't find any useful usages on Sourcegraph as well.

@tharakadesilva
Copy link
Contributor Author

tharakadesilva commented Dec 15, 2024

Adding shell: true here seems to solve the issue. 🎉 I'll send a PR for it.

Ref: https://stackoverflow.com/a/44987029

There be a few more 🐉 to slay, at least I am unblocked for now.

let args: string[];
if (easEnvironment) {
commandLine = await which('eas', true);
const commandToExecute = ['npx', ...baseArguments].join(' ').replace(/"/g, '\\"');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice catch on the quotes, and especially nice catch on the replace!

@wschurman wschurman self-requested a review December 18, 2024 22:11
Copy link
Member

Going to do another round of debugging/testing with a local project of mine. It seems like adding shell: true makes running the command in a normal prompt not work (even if it works here):

$ neas env:exec preview "npx expo config --json --type public"
No environment variables with visibility "Plain text" and "Sensitive" found for the "preview" environment on EAS servers.

Running command: npx expo config --json --type public
[stdout] Entering npm script environment at location:
[stdout] /Users/wschurman/temp/pkfsapjfasafjpfajaf
[stdout] Type 'exit' or ^D when finished

@wschurman wschurman requested a review from szdziedzic December 18, 2024 22:12
@tharakadesilva
Copy link
Contributor Author

Added these two commits, I am not too happy with them. 😓

  • 06f1224 (the stdout processing needs some "massaging" as there is an extra stdout calls to print saying that the expo env is being used and the env vars are being loaded.
  • 88a9191 (not entirely sure if this is necessary, but the stdout seems to be polluted when we do Promise.all; I did this very late at night so I might have been hallucinating a bit too; I'll double check if we need this).

@tharakadesilva
Copy link
Contributor Author

tharakadesilva commented Dec 18, 2024

Going to do another round of debugging/testing with a local project of mine.

I was running a few tests as well, but I ran into an issue and I didn't get a chance to take a look at it again.

My android build works fine, but on iOS I am getting an error saying that the fingerprint has changed (similar to this).

These are my builds:

This is a new template project that I am working on to make my life easier, not one of the projects where I have continuous-deploy-fingerprint already working. I will try with one of those projects as well. It might be a misconfiguration in my new template project.

Sorry for the delay, I haven't gotten a chance to work on this during the week. I'll try to take a look again towards the end of the week.

@tharakadesilva
Copy link
Contributor Author

It seems like adding shell: true makes running the command in a normal prompt not work (even if it works here):

$ neas env:exec preview "npx expo config --json --type public"
No environment variables with visibility "Plain text" and "Sensitive" found for the "preview" environment on EAS servers.

Running command: npx expo config --json --type public
[stdout] Entering npm script environment at location:
[stdout] /Users/wschurman/temp/pkfsapjfasafjpfajaf
[stdout] Type 'exit' or ^D when finished

Oof, that is not good. Maybe spawnAsync requires better args? Unfortunately, I am not a node expert, but if you don't find a good solution, I'll take a look at it along with the fingerprinting issue that I was seeing.

Copy link
Member

@szdziedzic szdziedzic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The env:exec/--environment parts look reasonable to me

@tharakadesilva
Copy link
Contributor Author

I started with these:

image

These are the test I ran with their observations:

  1. Initial publish (iOS build | Android build | iOS update | Android update)
  • New builds are created for iOS and Android.
  • Updates are created.
  • Update fingerprints match the build fingerprints.
  • BUILD_VAR and EXPO_PUBLIC_UPDATE_VAR are available when build fingerprint is made.
  • EXPO_PUBLIC_UPDATE_VAR is available to be used during app update, but BUILD_VAR is not.
  1. Rerun pipeline (iOS update | Android update)
  • No new builds are created for iOS and Android.
  • Updates are created.
  • Update fingerprints match the build fingerprints.
  • BUILD_VAR and EXPO_PUBLIC_UPDATE_VAR are available when build fingerprint is made.
  • EXPO_PUBLIC_UPDATE_VAR is available to be used during app update, but BUILD_VAR is not.
  1. Update BUILD_VAR to new_build_value (iOS update | Android update)
  • No new builds are created for iOS and Android.
  • Updates are created.
  • Update fingerprints match the build fingerprints.
  • BUILD_VAR and EXPO_PUBLIC_UPDATE_VAR are available when build fingerprint is made.
  • EXPO_PUBLIC_UPDATE_VAR is available to be used during app update, but BUILD_VAR is not.
  1. Update EXPO_PUBLIC_UPDATE_VAR to new_update_value (iOS update | Android update)
  • No new builds are created for iOS and Android.
  • Updates are created.
  • Update fingerprints match the build fingerprints.
  • BUILD_VAR and EXPO_PUBLIC_UPDATE_VAR are available when build fingerprint is made.
  • EXPO_PUBLIC_UPDATE_VAR is available to be used during app update, but BUILD_VAR is not.

@wschurman
Copy link
Member

Just coming back from vacation, looking at this again now.

@wschurman
Copy link
Member

wschurman commented Jan 6, 2025

I'm going to make some changes to the eas env:exec command to make it just a pass-through and not do any logging itself. i.e. make programmatic usage of it more reasonable and not need to filter the results.

@wschurman
Copy link
Member

wschurman commented Jan 6, 2025

expo/eas-cli#2800

@tharakadesilva
Copy link
Contributor Author

Thanks Will!

Copy link
Member

@wschurman wschurman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Back to your queue to use the --non-interactive flag on env:exec as well as your PR in eas-cli once it lands. I think this should be good to go then and I'll do a full round of testing in my test repos that use this action.

@tharakadesilva
Copy link
Contributor Author

Back to your queue to use the --non-interactive flag on env:exec as well as your PR in eas-cli once it lands. I think this should be good to go then and I'll do a full round of testing in my test repos that use this action.

Will address this over the weekend.

@tharakadesilva
Copy link
Contributor Author

Added these two commits, I am not too happy with them. 😓

Removed these commits and switched to --non-interactive. Things are working like a charm! Thanks for all the help, Will.

Once this is merged I need to start rewriting git history to remove the eas-cli large files I committed for testing... 😅

Copy link
Member

@wschurman wschurman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Merged in 8134c7a. Thanks for putting in the effort to get this fully working!

@wschurman wschurman closed this Jan 13, 2025
@tharakadesilva
Copy link
Contributor Author

Thanks and thanks for all the help and guidance!

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

Successfully merging this pull request may close these issues.

3 participants