Repository navigation
ci: tie the demo app's Rails defaults to the CI Rails matrix #22
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
Open
developerz-ai
wants to merge
4
commits into
main
Choose a base branch
from
dz/tie-the-app-s-rails-load-defaults-to-the-ci--43ec5176
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
cdcbb34
ci: tie the demo app's Rails defaults to the CI Rails matrix
developerz-ai[bot] 09a4dc1
chore(babysit): land Gemfile.lock
developerz-ai[bot] 35271dd
chore(babysit): land AGENTS.md (+3 more)
developerz-ai[bot] 14174b6
Merge commit 'b69cba8f6766c92d0113c760d00e5ab6a376ba7e' into dz/tie-t…
developerz-ai[bot] File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| #!/usr/bin/env ruby | ||
| # frozen_string_literal: true | ||
|
|
||
| # Guard: the demo app's Rails floor, the floor the gem advertises and the | ||
| # oldest Rails line of the CI matrix must be the same version. | ||
| # | ||
| # ruby bin/rails-defaults-check # app floor vs README.md, llms.txt, AGENTS.md | ||
| # ruby bin/rails-defaults-check '["7.2","8.0"]' # ... and vs the matrix's oldest entry | ||
| # | ||
| # Exits 1 and names every version compared when they drift, 0 when they | ||
| # agree. Stdlib only: no Bundler, no Rails, no network. | ||
|
|
||
| require 'json' | ||
| require 'open3' | ||
| require 'rbconfig' | ||
|
|
||
| ROOT = File.expand_path('..', __dir__) | ||
| ADVERTISED_FILES = %w[README.md llms.txt AGENTS.md].freeze | ||
| ADVERTISED_FLOOR = /Rails (\d+(?:\.\d+)*)\+/ | ||
|
|
||
| def app_floor | ||
| out, status = Open3.capture2e(RbConfig.ruby, File.join(ROOT, 'bin', 'rails-versions'), '--floor') | ||
| abort "bin/rails-versions --floor failed:\n#{out}" unless status.success? | ||
|
|
||
| out.strip | ||
| end | ||
|
|
||
| def advertised_floors(file) | ||
| source = File.read(File.join(ROOT, file)) | ||
| source.scan(ADVERTISED_FLOOR).flatten.uniq | ||
| end | ||
|
|
||
| def matrix_floor(json) | ||
| lines = JSON.parse(json) | ||
| unless lines.is_a?(Array) && !lines.empty? && lines.all?(String) | ||
| abort "Rails matrix must be a non-empty array of versions, got: #{json}" | ||
| end | ||
|
|
||
| lines.min_by { |line| Gem::Version.new(line) } | ||
| rescue JSON::ParserError, ArgumentError => e | ||
| abort "Could not read the Rails matrix #{json.inspect}: #{e.message}" | ||
| end | ||
|
|
||
| def same_version?(one, other) | ||
| Gem::Version.new(one) == Gem::Version.new(other) | ||
| rescue ArgumentError | ||
| one == other | ||
| end | ||
|
|
||
| floor = app_floor | ||
| reported = [['app floor (config/application.rb)', floor]] | ||
| problems = [] | ||
|
|
||
| ADVERTISED_FILES.each do |file| | ||
| versions = advertised_floors(file) | ||
| reported << [file, versions.empty? ? 'no "Rails X.Y+" advertised' : versions.join(', ')] | ||
| problems << file unless versions.size == 1 && same_version?(versions.first, floor) | ||
| end | ||
|
|
||
| matrix = ARGV[0] | ||
| if matrix | ||
| oldest = matrix_floor(matrix) | ||
| reported << ['CI matrix (oldest entry)', oldest] | ||
| problems << 'CI matrix' unless same_version?(oldest, floor) | ||
| end | ||
|
|
||
| if problems.empty? | ||
| summary = reported.map { |label, version| "#{label}: #{version}" }.join(', ') | ||
| puts "Rails floor #{floor}: #{summary} agree." | ||
| exit 0 | ||
| end | ||
|
|
||
| warn 'Rails floor mismatch:' | ||
| reported.each { |label, version| warn " #{label}: #{version}" } | ||
| warn "Align #{problems.join(', ')} with config/application.rb: bin/rails-versions derives the CI matrix from it." | ||
| exit 1 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| require 'fileutils' | ||
| require 'json' | ||
| require 'open3' | ||
| require 'rbconfig' | ||
| require 'tmpdir' | ||
|
|
||
| # Offline guard for the demo app's Rails floor: the app, the floor the gem | ||
| # advertises and the CI matrix must agree. No Rails, no network. | ||
| RSpec.describe 'bin/rails-defaults-check' do | ||
| let(:root) { File.expand_path('../..', __dir__) } | ||
| let(:app_config) { File.join(root, 'config', 'application.rb') } | ||
| let(:app_floor) { File.read(app_config)[/config\.load_defaults\s+(\d+(?:\.\d+)*)/, 1] } | ||
| # The files that advertise the floor the gem supports: the guard compares | ||
| # each of them with the app's floor and names the ones that drift. | ||
| let(:advertised_files) { %w[README.md llms.txt AGENTS.md] } | ||
| # A Rails version the app does not use: the next major, derived so a | ||
| # legitimate floor change needs no edit here. | ||
| let(:divergent_floor) { "#{app_floor.to_i + 1}.0" } | ||
|
|
||
| def run_script(*args) | ||
| Open3.capture2e(RbConfig.ruby, *args, chdir: root) | ||
| end | ||
|
|
||
| # A copy of the files the guard reads, so a drifted copy can be checked | ||
| # without touching the checkout. | ||
| def copy_guard_tree(dir) | ||
| FileUtils.mkdir_p(File.join(dir, 'bin')) | ||
| FileUtils.mkdir_p(File.join(dir, 'config')) | ||
| FileUtils.cp(app_config, File.join(dir, 'config', 'application.rb')) | ||
| %w[rails-defaults-check rails-versions].each do |script| | ||
| FileUtils.cp(File.join(root, 'bin', script), File.join(dir, 'bin', script)) | ||
| end | ||
| advertised_files.each { |file| FileUtils.cp(File.join(root, file), File.join(dir, file)) } | ||
| end | ||
|
|
||
| it 'derives the Rails floor from the demo app' do | ||
| stdout, status = run_script(File.join(root, 'bin', 'rails-versions'), '--floor') | ||
|
|
||
| expect(status).to be_success | ||
| expect(app_floor).to match(/\A\d+(\.\d+)*\z/) | ||
| expect(stdout.strip).to eq(app_floor) | ||
| end | ||
|
|
||
| it 'passes when the app floor and the advertised floor agree' do | ||
|
developerz-ai[bot] marked this conversation as resolved.
Resolved
|
||
| stdout, status = run_script(File.join(root, 'bin', 'rails-defaults-check')) | ||
|
|
||
| expect(status).to be_success | ||
| expect(stdout).to include("app floor (config/application.rb): #{app_floor}") | ||
| # Every advertised file is compared and reported with the floor found in | ||
| # it: a guard that stopped comparing them would not name them at all. | ||
| advertised_files.each { |file| expect(stdout).to include("#{file}: #{app_floor}") } | ||
| end | ||
|
|
||
| it 'fails when an advertised file drifts from the app floor' do | ||
| Dir.mktmpdir do |dir| | ||
| copy_guard_tree(dir) | ||
| File.write(File.join(dir, 'AGENTS.md'), "Rails #{divergent_floor}+\n") | ||
|
|
||
| stdout, status = run_script(File.join(dir, 'bin', 'rails-defaults-check')) | ||
|
|
||
| expect(status).not_to be_success | ||
| expect(stdout).to include("app floor (config/application.rb): #{app_floor}") | ||
| expect(stdout).to include("AGENTS.md: #{divergent_floor}") | ||
| expect(stdout).to include('Align AGENTS.md with config/application.rb') | ||
| end | ||
| end | ||
|
|
||
| it 'fails when the CI matrix starts at another Rails than the app' do | ||
|
developerz-ai[bot] marked this conversation as resolved.
Resolved
|
||
| stdout, status = run_script(File.join(root, 'bin', 'rails-defaults-check'), JSON.generate([divergent_floor])) | ||
|
|
||
| expect(status).not_to be_success | ||
| expect(stdout).to include("app floor (config/application.rb): #{app_floor}") | ||
| expect(stdout).to include("CI matrix (oldest entry): #{divergent_floor}") | ||
| expect(stdout).to include('Align CI matrix with config/application.rb') | ||
| end | ||
| end | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.