helaili / jekyll-action

A GitHub Action to publish Jekyll based content as a GitHub Pages site
MIT License
250 stars 120 forks source link

Could not find 'bundler' (1.17.2) #16

Closed MichaelCurrin closed 3 years ago

MichaelCurrin commented 4 years ago

I am enjoying your action thanks. I am using it to write a tutorial on the Jekyll site. I have am issues around bundler and lock file and would like to get this sorted out before I get the tutorial through. I hope you can help.

This problem similar to #13 but different.

When run Bundle, I get Gemfile.lock file which includes Bundled with 1.17.2. This causes a failed build with your action, which cannot find that version.

If I remove the lockfile by ignoring it, the build works. But I would prefer to keep a lockfile.

Do you have any recommendations?

Or is there a fix you can make? Such as allowing the bundle version to be set as a parameter in the workflow file. Rather than letting Bundle version be the latest (not pinned anymore in Dockerfile) or pinned to a version that I don't use.

MichaelCurrin commented 4 years ago

Gemfile.lock:

BUNDLED WITH
   1.17.2

Here is the error I get.

Starting the Jekyll Action /usr/local/lib/ruby/2.7.0/rubygems.rb:275:in `find_spec_for_exe': Could not find 'bundler' (1.17.2) required by your /github/workspace/Gemfile.lock. (Gem::GemNotFoundException)

helaili commented 4 years ago

Can you point at a repo with a sample?

MichaelCurrin commented 4 years ago

Sure.

Here's a build with the failing step.

https://github.com/MichaelCurrin/jekyll-actions-quickstart/runs/583490955?check_suite_focus=true

And the lockfile as it was at that build.

https://github.com/MichaelCurrin/jekyll-actions-quickstart/blob/a4de808014cf38ac5e14a55c7c900d2a4e9b87b3/Gemfile.lock

MichaelCurrin commented 4 years ago

Even if I take bundler out of Gemfile and lockfile dependencies, then bundler is still listed in BUNDLED WITH at the bottom of the lockfile and that version 1.17.2 can't be found.

helaili commented 4 years ago

The problem you are running into is described here.

Is there a reason why you want to specify the bundler version in your Gemfile? If you look at my code, Gemfile.lock is committed in the repo but there's nothing abount bundler in the Gemfile.

MichaelCurrin commented 4 years ago

Thanks that link is relevant. I see it's a bug.

I added that bundle line in my Gemfile as an experiment solution but it meant the error was the same as without it. The reason yours works is your lock file bundler matches your container's bundle version. I could upgrade mine but then my other projects need to match my new system version. And then I'm always tied to the version of this action. (Or I edit or drop my lock file.)

That's why I suggested a workflow param so then the build steps use an given bundler version. e.g. 1.17.2

A larger change would be to drop bundler use for the action. Netlify does great with jekyll build and no bundler (and it insists on a lock file existing). So just an idea to consider one day if bundler gives other hassles

limjh16 commented 4 years ago

Hey, According to the bundler 2 upgrade page, The version of Bundler in the BUNDLED WITH section in Gemfile.lock is read by Bundler to determine which version of Bundler should run, so not really sure why the error still pops up..? Also, Netlify also uses bundler (see https://community.netlify.com/t/builds-bundler-version-from-gemfile-lock-now-installed-and-used/5561). I think it would be difficult to manage a Gemfile without it.

MichaelCurrin commented 4 years ago

@limjh16 The error here is that the actions container has Bundler 2.1.4 installed, so if lockfile specifies any other version, the build fails.

Yes as that article says, Netlify is smart enough to work any Bundler version in a lock file, not just the latest. It might do a selective install of Bundler - I got an error trying to install two versions of Bundler.

I did an experiment now - deployed a site with Gemfile and no lockfile and Bundler was still used on Netlify. Sorry, I just assumed it wasn't used on Netlify because the build command is typically jekyll build not bundle exec jekyll build.

MichaelCurrin commented 4 years ago

Hi, I've solved the issue using a fork and feature branch and would like to share here. 🚀

I set a custom BUNDLER_VERSION variable in my workflow file's env. And that gets used in Dockerfile. And if the value is not set, then Dockerfile falls back to hardcoded value of 2.1.4.

https://github.com/MichaelCurrin/jekyll-action/pull/1

I tested my solution by setting 1.17.3 in my sample test.yaml workflow file and changing the lockfile use to 1.17.3. There are no errors like in my original comment at the top of this issue and the site builds.


Notes

helaili commented 4 years ago

Regarding the JEKYLL_SRC, it is resolved automatically based on the directory that contains _config.yml. You can overload this behavior by setting it yourself with the input.

Did you see @limjh16's comment on #17? Seems like there is another interesting solution.

limjh16 commented 4 years ago

Hey, I was trying these changes but I noticed this in the github action logs: https://github.com/MichaelCurrin/jekyll-action/runs/615180060#step:3:491 this shows that bundler 1 is actually not being installed, it auto-updates it to bundler 2 inside the workflow. This is shown again here: https://github.com/MichaelCurrin/jekyll-action/runs/615180060#step:3:414

MichaelCurrin commented 4 years ago

Okay thanks yes I see JS action as an alternative to help with my issue.

It's good to see INPUT_JEKYLL_SRC rename in there too.

@limjh16 okay thanks. I built and posted in a hurry. I'd made a typo and also I've rename to a different variable. I still have an issue where BUNDLE_V is not being picked up in Dockerfile when set in test.yaml. so I'm missing something there.

So my bundle is still working on 2.1.2 rather than an older version but weirdly the lock file BUNDLED WITH 1.17.3 is either not being read or it's been read and ignored as there's no conflict.

limjh16 commented 4 years ago

Hey, if you need some reference, here is how setup-ruby actions does it: https://github.com/ruby/setup-ruby/blob/master/index.js#L126 I'm not sure how to convert that javascript to a bash script though...

MichaelCurrin commented 4 years ago

Oh yeah that's nicer than having to configure a version on the workflow file.

I can see what the JS logic is and could translate to bash. That could be used in bash script which is run in the Dockerfile steps to get a version from the file or empty string, then use it for the installing of bundle.

MichaelCurrin commented 4 years ago

That JS logic can be replaced with grep

Searching for a grep I found the exact solution I need and on a page linked here near the top.

gem install bundler -v "$(grep -A 1 "BUNDLED WITH" Gemfile.lock | tail -n 1)"

Link again: Can't find gem bundler

So I want to use that. but i will just confirm first that it works when there is no lock file and make adjustments.

MichaelCurrin commented 4 years ago

I am getting closer but still stuck.

The ENV part is evaluated in the build not the host, based on https://github.com/moby/moby/issues/29110#issuecomment-453718228

So I tried to run this and the COPY failed for the lock file.

COPY Gemfile.lock /
ENV BUNDLE_VSN="$(grep -A 1 'BUNDLED WITH' Gemfile.lock | tail -n 1)"
RUN gem install bundler -v "${BUNDLE_VSN:-2.1.4}"

Build https://github.com/MichaelCurrin/jekyll-action/runs/641130291?check_suite_focus=true

MichaelCurrin commented 4 years ago

BTW I created a new branch and pulled latest changes

elstudio commented 4 years ago

Well one way to fix/work around this is to update bundler on your local system to 2.1.4, then remove Gemfile.lock and re-run bundle install.

MichaelCurrin commented 4 years ago

Thanks for the suggestion @elstudio but that's not a long term solution for me. One can only have one version of bundle installed (and I don't want to go down multiple Ruby version road).

And I don't want my system's bundle version on multiple laptops to be determined by what one Github Action's hardcoded Bundler-2.1.4 version is pinned too.

MichaelCurrin commented 4 years ago

Also, I made another change to my branch - my logic actually now picks up the Bundler version up dynamically from the Gemfile.lock as confirmed by output.

 Step 8/12 : RUN BUNDLE_VSN="$(grep -A 1 'BUNDLED WITH' /Gemfile.lock | tail -n 1)" ; gem install bundler -v "${BUNDLE_VSN:-2.1.4}"
 ---> Running in 8b350d52f63a
Successfully installed bundler-1.7.2

Then it complains about event machine error.

https://github.com/MichaelCurrin/jekyll-action/runs/741441989?check_suite_focus=true

helaili commented 3 years ago

lockfile is no longer required so it should be good now.