HashNuke / heroku-buildpack-elixir

Heroku Buildpack for Elixir with nitro boost
MIT License
810 stars 304 forks source link

Will use cached Elixir version even if Erlang version changes #178

Closed jbrowning closed 3 years ago

jbrowning commented 3 years ago

This buildpack does not ensure that the cached Elixir version is compatible when the Erlang major version is updated. This results in an error similar to the following:

-----> Cleaning all cache to force rebuilds
-----> Using cached Erlang 22.2.3
-----> Installing Erlang 22.2.3

-----> Using cached Elixir v1.11.2
-----> Installing Elixir v1.11.2
-----> Installing Hex
remote: init terminating in do_boot ({undef,[{elixir,start_cli,[],[]},{init,start_eremote: {init,do_boot,3,[]}]})
       {"init terminating in do_boot",{undef,[{elixir,start_cli,[],[]},{init,start_remote: ,{init,do_boot,3,[]}]}}
remote:
remote: Crash dump is being written to: erl_crash.dump...done
-----> Installing rebar
remote: init terminating in do_boot ({undef,[{elixir,start_cli,[],[]},{init,start_eremote: {init,do_boot,3,[]}]})
       {"init terminating in do_boot",{undef,[{elixir,start_cli,[],[]},{init,start_remote: ,{init,do_boot,3,[]}]}}
remote:
remote: Crash dump is being written to: erl_crash.dump...done
-----> Fetching app dependencies with mix
remote: init terminating in do_boot ({undef,[{elixir,start_cli,[],[]},{init,start_eremote: {init,do_boot,3,[]}]})
       {"init terminating in do_boot",{undef,[{elixir,start_cli,[],[]},{init,start_remote: ,{init,do_boot,3,[]}]}}
remote:
remote: Crash dump is being written to: erl_crash.dump...done

To recreate:

jesseshieh commented 3 years ago

Thanks for the bug report @jbrowning. I guess we could try and implement something to check the compatibility matrix described here https://hexdocs.pm/elixir/compatibility-and-deprecations.html#compatibility-between-elixir-and-erlang-otp

Perhaps in this function which checks the erlang version. https://github.com/HashNuke/heroku-buildpack-elixir/blob/master/lib/canonical_version.sh#L20

Any help implementing this would be greatly appreciated!

hez commented 3 years ago

We had this happen and had to turn off caching completely. We could turn it on then turn it off on lang update but that seems like a lot of work.

hez commented 3 years ago

@jesseshieh I would suggest tagging the cache with the otp + elixir ver and invalidating it if it changes at all. That would be easiest and cover all bases.

jesseshieh commented 3 years ago

Thanks @hez. I like that suggestion.

Right now, according to this we basically check for ${cache_path}/elixir-${elixir_version}.zip

We could change this to ${cache_path}/elixir-${elixir_version}-otp-${erlang_version}.zip

The file we download usually looks something like this anyway:

-----> Fetching Elixir v1.10.3 for OTP 22 from https://repo.hex.pm/builds/elixir/v1.10.3-otp-22.zip

The code that fetches it even uses the otp_version and then throws it away when writing the elixir_download_file. I wonder if perhaps the otp_version is all we need rather than the entire erlang_version.

jbrowning commented 3 years ago

@jesseshieh Yeah elixir_version + otp_version like the original filename is all you need to retain in order to fix this. Minor Erlang version changes will still download the same OTP version.

jesseshieh commented 3 years ago

I just submitted a pull request with a potential fix. I tested it briefly and it seems to work. If you guys want to try it out, change your buildpack to https://github.com/jesseshieh/heroku-buildpack-elixir#js/elixir-otp-version-cache and see if everything works okay.