Skip to content

Commit

Permalink
Add rails_release_sanity_check action
Browse files Browse the repository at this point in the history
  • Loading branch information
etagwerker committed Oct 8, 2024
1 parent bc0d5bc commit 387f62e
Show file tree
Hide file tree
Showing 6 changed files with 213 additions and 1 deletion.
45 changes: 45 additions & 0 deletions .github/workflows/rails_release_sanity_check.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Rails Release Sanity Check

on:
workflow_dispatch:
inputs:
bundler_version:
description: 'Bundler Version'
required: true
type: string
rails_version:
description: 'Rails version to use in the format 6.1.0'
required: true
default: '6.1.0'
ruby_version:
description: 'Ruby Version'
required: true
type: string

jobs:
rails_release_sanity_check:
runs-on: ubuntu-latest

# env:
# RAILS_BUMP_API_KEY: ${{ secrets.RAILS_BUMP_API_KEY }}
# RAILS_BUMP_API_HOST: "https://api.railsbump.org"

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Ruby ${{ github.event.inputs.ruby_version }}
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ github.event.inputs.ruby_version }}

- name: Install Bundler ${{ github.event.inputs.bundler_version }}
run: |
gem uninstall --all --force --executables
gem install bundler -v ${{ github.event.inputs.bundler_version }}
- name: Install dependencies
run: bundle _${{ github.event.inputs.bundler_version }}_ install

- name: Run check_bundler script
run: ./exe/check_rails_release.sh --rails_version '${{ github.event.inputs.rails_version }}'
43 changes: 43 additions & 0 deletions exe/check_rails_release.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/usr/bin/env ruby

require 'json'
require 'optparse'
require_relative '../lib/rails_bump/checker'

options = {}
option_parser = OptionParser.new do |opts|
opts.banner = "Usage: check_rails_release [options]"

opts.on("-r", "--rails_version VERSION", "Specify the Rails version") do |v|
options[:rails_version] = v
end
end

begin
option_parser.parse!
require 'byebug'; byebug
if options.size != 1
puts option_parser
exit
end
rescue OptionParser::InvalidOption, OptionParser::MissingArgument
puts option_parser
exit 1
end

checker = RailsBump::Checker::RailsReleaseCheck.new(
rails_version: options[:rails_version]
)

result = checker.check

# puts "Reporting..."
# reporter = RailsBump::Checker::ResultReporter.new(result)
# reporter.report
# puts "Done reporting"

puts result.output
puts ""
puts "Success: #{result.success?}"

exit(0)
1 change: 1 addition & 0 deletions lib/rails_bump/checker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
require_relative "checker/version"
require_relative "checker/result"
require_relative "checker/bundle_locally_check"
require_relative "checker/rails_release_check"
require_relative "checker/result_reporter"

module RailsBump
Expand Down
84 changes: 84 additions & 0 deletions lib/rails_bump/checker/rails_release_check.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
require 'fileutils'
require 'stringio'

module RailsBump
module Checker
class RailsReleaseCheck
def initialize(opts = {})
@rails_version = opts[:rails_version] || "9.1.0"
@captured_output = ""
@result = nil
end

# This method checks a compat by actually attempting to install the compat's dependencies with the compat's Rails version locally. If the installation fails, the compat is marked as incompatible. If it succeeds, it is marked as compatible. If any of the dependencies have native extensions that cannot be built, the compat is marked as inconclusive.
# def check_with_bundler_locally
def check
puts "Checking compatibility:"
puts "Rails version #{@rails_version}"

begin
# Ensure the tmp directory exists
FileUtils.mkdir_p('tmp')

# Set up the environment and definition
Bundler.with_unbundled_env do
@captured_output = try_bundle_install

puts "✅ Compatible dependencies"
@result = Result.new(
rails_version: @rails_version,
success: true,
strategy: self.class.name,
output: @captured_output
)
end
rescue => err
puts "💔 Incompatible dependencies"
@result = Result.new(
rails_version: @rails_version,
success: false,
strategy: self.class.name,
output: "#{@captured_output}\n\nBundler error: #{err.message}\n\n#{err.backtrace}"
)
ensure
puts "Cleaning up temporary files..."
FileUtils.rm_rf('tmp')
end

@result
end

private

# Create a temporary Gemfile with the specified dependencies
def gemfile_content
result = <<~GEMFILE
source 'https://rubygems.org'
gem 'rails', '#{@rails_version}'
GEMFILE

result
end

def try_bundle_install
File.write('tmp/Gemfile', gemfile_content)

puts "Checking with temporary Gemfile: \n\n#{gemfile_content}\n\n"

# Build the definition from the temporary Gemfile
definition = Bundler::Definition.build('tmp/Gemfile', 'tmp/Gemfile.lock', nil)

original_stdout = $stdout
$stdout = StringIO.new
begin
Bundler::Installer.install(Bundler.root, definition)
ensure
@captured_output = $stdout.string
$stdout = original_stdout
end

@captured_output
end
end
end
end
2 changes: 1 addition & 1 deletion lib/rails_bump/checker/result.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module Checker
class Result
attr_reader :compat_id, :dependencies, :output, :rails_version, :strategy, :success

def initialize(success: false, output: "", rails_version:, dependencies:, compat_id: nil, strategy:)
def initialize(success: false, output: "", rails_version:, dependencies: {}, compat_id: nil, strategy:)
@success = success
@output = output
@rails_version = rails_version
Expand Down
39 changes: 39 additions & 0 deletions spec/rails_bump/checker/rails_release_check_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
require 'spec_helper'

RSpec.describe RailsBump::Checker::RailsReleaseCheck do
describe '#check' do
let(:version) { "6.1.0" }

before do
@checker = RailsBump::Checker::RailsReleaseCheck.new(
rails_version: version
)
end

context "when version of Rails does not exist" do
let(:version) { "999.9.9" }

it "returns success => false" do
result = @checker.check

expect(result.success?).to be_falsey
end

it "returns output with useful details" do
msg = "Could not find gem 'rails (= 999.9.9)' in rubygems"

result = @checker.check

expect(result.output).to include(msg)
end
end

context "when version of Rails exists and it is compatible" do
it 'installs dependencies without errors' do
result = @checker.check

expect(result.success?).to be_truthy
end
end
end
end

0 comments on commit 387f62e

Please sign in to comment.