-
Notifications
You must be signed in to change notification settings - Fork 0
Add BUNDLE_GEMFILE-aware dual-boot support (rebased on v359) #4
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
base: sync_v359
Are you sure you want to change the base?
Changes from all commits
a034ccb
48f1020
d18d949
535bb1f
f8b404f
93e8262
f128dab
d4dfee0
7b1de7e
28e61bf
da7f392
709a88d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,59 +1,79 @@ | ||
| # Heroku Buildpack for Ruby | ||
| # Heroku Buildpack for Ruby (next_rails dual-boot fork) | ||
|
|
||
|  | ||
|
|
||
| This is a [Heroku Buildpack](http://devcenter.heroku.com/articles/buildpacks) for Ruby, Rack, and Rails apps. It uses [Bundler](https://bundler.io) for dependency management. | ||
| This is a fork of [Heroku's official Ruby buildpack](https://github.com/heroku/heroku-buildpack-ruby). The **only** thing it adds is dual-boot support through the `BUNDLE_GEMFILE` environment variable. For all standard Ruby, Rack, and Rails buildpack behavior, and for full documentation, use the official buildpack and the [Heroku Ruby Support](https://devcenter.heroku.com/articles/ruby-support) docs. | ||
|
|
||
| This buildpack requires 64-bit Linux. | ||
| > ## ⚠️ Read this first: changing `BUNDLE_GEMFILE` requires a rebuild, not just a config change | ||
| > | ||
| > Heroku triggers a **re-release but not a rebuild** when you change a config var. The build is what installs gems, so flipping `BUNDLE_GEMFILE` on its own never installs the other Rails version's gems. | ||
| > | ||
| > Example: an app built with Rails 6.1 only has 6.1 gems in its slug. If you then change `BUNDLE_GEMFILE` to `Gemfile.next` (Rails 7.0): | ||
| > | ||
| > - Heroku runs a new release with the changed env but does **not** rebuild the slug. | ||
| > - The slug still has only the previous version's gems. In some cases the re-release may fail, and Heroku might revert the config var to its previous value. If that happens, the env change ends up **not actually applied at runtime**, so Heroku reports the var changed while the app keeps running the previous version. Confusing, but expected. | ||
| > | ||
| > **To switch versions: change `BUNDLE_GEMFILE` and then trigger a deploy (e.g. push a commit) so the correct gems are installed at build time.** Do not rely on flipping the config var by itself. | ||
|
|
||
| ## Usage | ||
| ## What this fork is for | ||
|
|
||
| ### Ruby | ||
| It lets a single app switch between its current Gemfile and a [`next_rails`](https://github.com/fastruby/next_rails)-style alternative (e.g. `Gemfile.next`) at deploy time. `next_rails` is maintained by [FastRuby.io](https://www.fastruby.io). | ||
|
|
||
| Example Usage: | ||
| - `BUNDLE_GEMFILE` **unset** → behaves exactly like the official `heroku/ruby` buildpack (uses `Gemfile` / `Gemfile.lock`). Drop-in replacement. | ||
| - `BUNDLE_GEMFILE=Gemfile.next` → builds and runs against `Gemfile.next` / `Gemfile.next.lock`. | ||
|
|
||
| $ ls | ||
| Gemfile Gemfile.lock | ||
| ## Usage | ||
|
|
||
| $ heroku create --buildpack heroku/ruby | ||
| 1. Confirm the app boots locally on the next version: | ||
|
|
||
| $ git push heroku main | ||
| ... | ||
| -----> Heroku receiving push | ||
| -----> Fetching custom buildpack | ||
| -----> Ruby app detected | ||
| -----> Installing dependencies using Bundler version 1.1.rc | ||
| Running: bundle install --without development:test --path vendor/bundle --deployment | ||
| Fetching gem metadata from http://rubygems.org/.. | ||
| Installing rack (1.3.5) | ||
| Using bundler (1.1.rc) | ||
| Your bundle is complete! It was installed into ./vendor/bundle | ||
| Cleaning up the bundler cache. | ||
| -----> Discovering process types | ||
| Procfile declares types -> (none) | ||
| Default types for Ruby -> console, rake | ||
| ```sh | ||
| BUNDLE_GEMFILE=Gemfile.next bundle exec rails -v | ||
| ``` | ||
|
|
||
| The buildpack will detect your app as Ruby if it has a `Gemfile` and `Gemfile.lock` files in the root directory. It will then proceed to run `bundle install` after setting up the appropriate environment for [ruby](http://ruby-lang.org) and [Bundler](https://bundler.io). | ||
| 2. Point the app at this fork (pin to a branch or tag): | ||
|
|
||
| ## Documentation | ||
| ```sh | ||
| heroku buildpacks:set https://github.com/fastruby/heroku-buildpack-ruby#use_gemfile_next_v359 -a <app> | ||
| ``` | ||
|
|
||
| For more information about using Ruby and buildpacks on Heroku, see these Dev Center articles: | ||
| 3. Set the config var: | ||
|
|
||
| - [Heroku Ruby Support](https://devcenter.heroku.com/articles/ruby-support) | ||
| - [Getting Started with Ruby on Heroku](https://devcenter.heroku.com/articles/getting-started-with-ruby) | ||
| - [Getting Started with Rails 7 on Heroku](https://devcenter.heroku.com/articles/getting-started-with-rails7) | ||
| - [Buildpacks](https://devcenter.heroku.com/articles/buildpacks) | ||
| - [Buildpack API](https://devcenter.heroku.com/articles/buildpack-api) | ||
| ```sh | ||
| heroku config:set BUNDLE_GEMFILE=Gemfile.next -a <app> | ||
| ``` | ||
|
|
||
| ## Hacking | ||
| 4. Deploy. This is the rebuild that installs the next gems (see the warning above): | ||
|
|
||
| To use this buildpack, fork it on Github. Push up changes to your fork, then create a test app with `--buildpack <your-github-url>` and push to it. | ||
| ```sh | ||
| git push heroku <branch>:main | ||
| ``` | ||
|
|
||
| ### Testing | ||
| 5. Verify: | ||
|
|
||
| ```sh | ||
| $ bundle exec hatchet install | ||
| ``` | ||
| ```sh | ||
| heroku run "bundle exec rails -v" -a <app> | ||
| ``` | ||
|
|
||
| To go back to the current version, unset the var and redeploy: | ||
|
|
||
| ```sh | ||
| $ bundle exec rake spec | ||
| heroku config:unset BUNDLE_GEMFILE -a <app> | ||
| # then deploy again | ||
| ``` | ||
|
|
||
| ## Alternative: a next-only buildpack | ||
|
|
||
| If you want an app that always runs the next version without managing `BUNDLE_GEMFILE`, use our sibling fork [`fastruby/heroku-buildpack-ruby-gemfile-next`](https://github.com/fastruby/heroku-buildpack-ruby-gemfile-next). It always uses `Gemfile.next` / `Gemfile.next.lock` and needs no `BUNDLE_GEMFILE`. To return to the current version, switch the app's buildpack back to the official `heroku/ruby`. | ||
|
|
||
| ## Documentation | ||
|
|
||
| This fork only changes which Gemfile drives the build. For everything else, see: | ||
|
|
||
| - [Official Heroku Ruby buildpack](https://github.com/heroku/heroku-buildpack-ruby) | ||
| - [Heroku Ruby Support](https://devcenter.heroku.com/articles/ruby-support) | ||
| - [Buildpacks](https://devcenter.heroku.com/articles/buildpacks) | ||
| - [next_rails](https://github.com/fastruby/next_rails) | ||
|
|
||
| ## License | ||
|
|
||
| See [LICENSE](LICENSE). Originally created by Heroku, Inc. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,10 +17,14 @@ | |
| begin | ||
| app_path = Pathname(ARGV[0]) | ||
| cache_path = Pathname(ARGV[1]) | ||
| gemfile_lock = LanguagePack.gemfile_lock(app_path: app_path) | ||
| Dir.chdir(app_path) | ||
|
|
||
| # Load user config vars from the env dir before we touch the Gemfile so that | ||
| # BUNDLE_GEMFILE (set as a Heroku config var) can steer which lockfile we | ||
| # read. Without this, gemfile_lock would always read Gemfile.lock regardless | ||
| # of the user's BUNDLE_GEMFILE setting. | ||
| LanguagePack::ShellHelpers.initialize_env(ARGV[2]) | ||
| gemfile_lock = LanguagePack.gemfile_lock(app_path: app_path) | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Heroku passes user config vars to buildpacks via a directory of files (one file per var), not as actual ENV entries. The path to that dir is ARGV[2] in ruby_compile.rb. Sequence before our fix: gemfile_lock = LanguagePack.gemfile_lock(...) # reads ENV["BUNDLE_GEMFILE"] → ""
Dir.chdir(app_path)
LanguagePack::ShellHelpers.initialize_env(...) # now user_env_hash["BUNDLE_GEMFILE"] = "Gemfile.next"
ENV["BUNDLE_GEMFILE"] # empty, Heroku doesn't set it in ENV
|| LanguagePack::ShellHelpers.user_env_hash[..] # empty too, initialize_env hasn't run yet
|| "Gemfile" # falls through to defaultSo it picked After moving the line below initialize_env, user_env_hash is populated first, gemfile_name resolves to |
||
| LanguagePack.call( | ||
| app_path: app_path, | ||
| cache_path: cache_path, | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@arielj are we going to merge this PR or keep it as the previous version? if so, we need to update this to main or probably just the URL will pickup the default branch.