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: cast environment variable values to string #218

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

edaniszewski
Copy link
Contributor

@edaniszewski edaniszewski commented Jun 23, 2020

This PR:

  • casts the values from environment configuration to strings prior to deploy to prevent GCF invalid argument error
  • adds test cases for various non-string environment values

Related:

Copy link
Contributor

@medikoo medikoo left a comment

Choose a reason for hiding this comment

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

Thank you @edaniszewski !

@medikoo
Copy link
Contributor

medikoo commented Jun 24, 2020

Still, wouldn't that be confusing to users?

What's the use case in passing non string values to entity which can only host strings?

@edaniszewski
Copy link
Contributor Author

I'm not sure that it would be all that confusing to users, at least not to me. I've done a fair amount of YAML configuring and I still end up having a mental disconnect at times -- even though I know env values are strings and I am configuring for env, I reliably throw in an int or bool into the yaml config. It doesn't necessarily help that different tools handle value type coercion a bit differently, for example docker-compose allows you to configure env values that are strings, ints (which is implicitly cast to string), or null types (which is excluded from env), but not bools.

I can see this approach of force-everything-to-be-a-string to be less desirable by some, in which case, I'd be happy to implement an alternative approach which adds validation in function compilation to check that env values are strings and error otherwise; this way it can at least error out early instead of having the error returned via google at deploy time.

Copy link
Contributor

@medikoo medikoo left a comment

Choose a reason for hiding this comment

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

@edaniszewski thanks for comment.

What handling do you find intutitive if someone puts:

environment:
  SOME_ENV_VAR: false

Or introduces an error as:

environment:
  dev: 
    SOME_ENV_VAR: foo

_.get(this, 'serverless.service.provider.environment'),
funcObject.environment // eslint-disable-line comma-dangle
),
(value) => value.toString()
Copy link
Contributor

Choose a reason for hiding this comment

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

This will crash on null

@edaniszewski
Copy link
Contributor Author

Hmm, thats a good point. For the case of

environment:
  SOME_ENV_VAR: false

perhaps I was coming at it more from a perspective of convenient and not intuitive, at least for how I'd use it, where having it casted implicitly makes configuring it slightly easier.

I think your point on edge cases is a good argument against this approach and more in favor of the approach where no implicit casting is done, but a validation check is run instead. Does that sound okay to you? If so, I'll close out this PR and work on that approach.

@medikoo
Copy link
Contributor

medikoo commented Jun 24, 2020

I think your point on edge cases is a good argument against this approach and more in favor of the approach where no implicit casting is done, but a validation check is run instead. Does that sound okay to you

I think it's fine to support coercion just for numbers (there's no ambiguity here I think)and let other types result with same error as it's now.

It is fine for me, if you patch it on top of this PR (we anyway squash merge to single commit)

@edaniszewski
Copy link
Contributor Author

@medikoo made the changes to coerce numbers to string and error in other cases.

not sure if using _.transform is the best way of doing it, so I'm open to suggestions for other approaches

Copy link
Contributor

@medikoo medikoo left a comment

Choose a reason for hiding this comment

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

@edaniszewski thanks for update! I've proposed I believed a cleaner approach. Let me know what you think

{},
_.get(this, 'serverless.service.provider.environment'),
funcObject.environment // eslint-disable-line comma-dangle
funcTemplate.properties.environmentVariables = _.transform(
Copy link
Contributor

Choose a reason for hiding this comment

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

It'll be nicer to use _.mapValues

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah, I initially used that approach, but thought that it would be useful to have the key name in the error message as well so the user would know which key was configured incorrectly. I wasn't sure how to easily access keys from mapValues for the error message, so I went with transform.

If including the env var name feels unnecessary, I can update to use mapValues for sure

Copy link
Contributor

Choose a reason for hiding this comment

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

In mapValues callback name is provided as second argument, and it's cleaner as you just return coerced value and do not need to overwrite it manually

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ah okay. sorry about my confusion there - I had misread the docs. Thanks for talking me through this. Just pushed an update.

Copy link
Contributor

@medikoo medikoo left a comment

Choose a reason for hiding this comment

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

@edaniszewski thanks for update. Still CI/CD fails now.

@edaniszewski
Copy link
Contributor Author

Woops. Thats what I get for not running tests before checking in code 🤦

@edaniszewski
Copy link
Contributor Author

@medikoo I've updated and fixed the issues causing CI to fail - I think this should be ready to go now.

Copy link
Contributor

@medikoo medikoo left a comment

Choose a reason for hiding this comment

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

Thank you @edaniszewski !

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

Successfully merging this pull request may close these issues.

2 participants