diff --git a/.github/workflows/dependabot-sync-saas-lockfile.yml b/.github/workflows/dependabot-sync-saas-lockfile.yml new file mode 100644 index 000000000..5afe97244 --- /dev/null +++ b/.github/workflows/dependabot-sync-saas-lockfile.yml @@ -0,0 +1,35 @@ +name: Sync Gemfile.saas.lock + +on: + push: + branches: + - "dependabot/bundler/**" + paths: + - Gemfile.lock + +permissions: + contents: write + +jobs: + sync: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v6 + + - uses: ruby/setup-ruby@v1 + with: + ruby-version: .ruby-version + + - name: Forward Gemfile.lock changes to Gemfile.saas.lock + run: bin/bundle-drift forward + + - name: Commit updated lockfile + run: | + git add Gemfile.saas.lock + if ! git diff --cached --quiet; then + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git commit -m "Sync Gemfile.saas.lock" + git push + fi diff --git a/Gemfile.lock b/Gemfile.lock index f937c83e8..1da09daa2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -149,7 +149,7 @@ GEM bindex (0.8.1) bootsnap (1.21.1) msgpack (~> 1.2) - brakeman (7.1.2) + brakeman (8.0.1) racc builder (3.3.0) bundler-audit (0.9.3) @@ -184,7 +184,7 @@ GEM erubi (1.13.1) et-orbi (1.4.0) tzinfo - faker (3.5.3) + faker (3.6.0) i18n (>= 1.8.11, < 2) ffi (1.17.2-aarch64-linux-gnu) ffi (1.17.2-aarch64-linux-musl) @@ -399,7 +399,7 @@ GEM ruby2_keywords (0.0.5) rubyzip (3.2.2) securerandom (0.4.1) - selenium-webdriver (4.39.0) + selenium-webdriver (4.40.0) base64 (~> 0.2) logger (~> 1.4) rexml (~> 3.2, >= 3.2.5) diff --git a/Gemfile.saas.lock b/Gemfile.saas.lock index b8982beb2..a8a0edbf4 100644 --- a/Gemfile.saas.lock +++ b/Gemfile.saas.lock @@ -229,7 +229,7 @@ GEM bindex (0.8.1) bootsnap (1.21.1) msgpack (~> 1.2) - brakeman (7.1.2) + brakeman (8.0.1) racc builder (3.3.0) bundler-audit (0.9.3) @@ -265,7 +265,7 @@ GEM erubi (1.13.1) et-orbi (1.4.0) tzinfo - faker (3.5.3) + faker (3.6.0) i18n (>= 1.8.11, < 2) ffi (1.17.2-aarch64-linux-gnu) ffi (1.17.2-aarch64-linux-musl) @@ -513,7 +513,7 @@ GEM ruby2_keywords (0.0.5) rubyzip (3.2.2) securerandom (0.4.1) - selenium-webdriver (4.39.0) + selenium-webdriver (4.40.0) base64 (~> 0.2) logger (~> 1.4) rexml (~> 3.2, >= 3.2.5) diff --git a/bin/bundle-drift b/bin/bundle-drift index 64fd23292..b208d0c9c 100755 --- a/bin/bundle-drift +++ b/bin/bundle-drift @@ -5,6 +5,7 @@ # Usage: # bin/bundle-drift [check] # check for drift (default subcommand) # bin/bundle-drift correct # restore alignment (Gemfile.saas.lock is authoritative) +# bin/bundle-drift forward # push Gemfile.lock changes into Gemfile.saas.lock require "bundler" require "fileutils" @@ -118,11 +119,63 @@ class GemfileDriftCorrector end end +class GemfileDriftForwarder + def forward + drift = GemfileDriftChecker.new.check + return puts "\nNothing to forward." if drift.empty? + + puts "\nForwarding Gemfile.lock versions into Gemfile.saas.lock...\n\n" + + original_content = File.read(GEMFILE_SAAS_LOCK) + patched_content = original_content.dup + + drift.each do |d| + old_entry = "#{d[:name]} (#{d[:saas]})" + new_entry = "#{d[:name]} (#{d[:oss]})" + puts " #{old_entry} → #{new_entry}" + patched_content.gsub!(old_entry, new_entry) + end + + File.write(GEMFILE_SAAS_LOCK, patched_content) + + puts "\n▸ Verifying alignment" + new_drift = GemfileDriftChecker.new.check + + if new_drift.empty? + puts "\n✓ Lock files are now in sync" + show_diff(original_content, patched_content) + else + puts "\n✗ Lock files still have drift after forwarding." + puts " Restoring original Gemfile.saas.lock." + File.write(GEMFILE_SAAS_LOCK, original_content) + exit 1 + end + end + + private + def show_diff(original, patched) + require "tempfile" + + Tempfile.create("gemfile-saas-lock-original") do |f| + f.write(original) + f.flush + + diff = `diff -u #{f.path} #{GEMFILE_SAAS_LOCK} 2>/dev/null` + unless diff.empty? + puts "\nChanges made to Gemfile.saas.lock:" + puts diff + end + end + end +end + case command = ARGV[0] || "check" when "check" exit 1 unless GemfileDriftChecker.new.check.empty? when "correct" GemfileDriftCorrector.new.correct +when "forward" + GemfileDriftForwarder.new.forward else - abort "Usage: bin/bundle-drift [check|correct]" + abort "Usage: bin/bundle-drift [check|correct|forward]" end diff --git a/config/brakeman.ignore b/config/brakeman.ignore index 90f9d53c6..25441a680 100644 --- a/config/brakeman.ignore +++ b/config/brakeman.ignore @@ -95,7 +95,7 @@ { "warning_type": "Remote Code Execution", "warning_code": 24, - "fingerprint": "b00571393e95a8c7d77b1ed963cfc5cc89333bc82f447cf8783549d817990305", + "fingerprint": "f13f9f972c3f026ab4509a66ac284b8b7c1ba6191a3c4c89d2e9fb4584478f6d", "check_name": "UnsafeReflection", "message": "Unsafe reflection method `safe_constantize` called on model attribute", "file": "app/models/notifier.rb", @@ -139,5 +139,5 @@ "note": "No user input allowed" } ], - "brakeman_version": "7.1.2" + "brakeman_version": "8.0.1" }