From 4c531a3762ceb0696fb36cb8f2d0a2f6027077c5 Mon Sep 17 00:00:00 2001 From: Paul DobbinSchmaltz Date: Fri, 22 Nov 2024 11:04:45 -0600 Subject: [PATCH] Add GitHub Actions + bump.rake to maintain ruby versions Using bump.rake also necessitated renaming MIT-LICENSE to LICENSE.txt, for uniformity with my other gems that use this same rake file. --- .github/workflows/ci.yml | 52 +++++++++++++++++++ Gemfile.lock | 2 +- LICENSE.txt | 21 ++++++++ MIT-LICENSE | 20 -------- rakelib/bump.rake | 106 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 180 insertions(+), 21 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 LICENSE.txt delete mode 100644 MIT-LICENSE create mode 100644 rakelib/bump.rake diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..78e2763 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,52 @@ +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. +# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake +# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby + +name: CI + +on: + pull_request: + push: + branches: + - main + +permissions: + contents: read + +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + ruby-version: ["3.1", "3.2", "3.3"] + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby-version }} + bundler-cache: true # runs `bundle install` and caches installed gems automatically + + - name: Run tests + run: bundle exec rake test + + rubocop: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: "3.3.6" + bundler-cache: true # runs `bundle install` and caches installed gems automatically + + - name: Run rubocop + run: bundle exec rubocop diff --git a/Gemfile.lock b/Gemfile.lock index 41798b5..15225c1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -286,4 +286,4 @@ DEPENDENCIES statusable! BUNDLED WITH - 2.3.27 + 2.5.23 diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..105e3a9 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2024 Paul DobbinSchmaltz + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/MIT-LICENSE b/MIT-LICENSE deleted file mode 100644 index 6e2e504..0000000 --- a/MIT-LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -Copyright Paul DobbinSchmaltz - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/rakelib/bump.rake b/rakelib/bump.rake new file mode 100644 index 0000000..6c2ad21 --- /dev/null +++ b/rakelib/bump.rake @@ -0,0 +1,106 @@ +# frozen_string_literal: true + +require "date" +require "open-uri" +require "yaml" + +desc "Update Bundler version, Ruby version, and LICENSE year in relevant files" +task :bump do + run_tasks(%w[ + bump:bundler + bump:ruby + bump:year + ]) +end + +namespace :bump do + desc "Update Bundler version to latest in Gemfile.lock" + task :bundler do + version = Gem.latest_version_for("bundler").to_s + replace_in_file("Gemfile.lock", /^BUNDLED WITH\n\s+(\d\S+)$/ => version) + end + + desc "Update Ruby version targets in relevant files" + task :ruby do + replace_in_file( + "statusable.gemspec", + /ruby_version = .*">= (.*)"/ => RubyVersions.lowest_supported_minor) + replace_in_file( + ".rubocop.yml", + /TargetRubyVersion: (.*)/ => RubyVersions.lowest_supported_minor) + replace_in_file( + ".github/workflows/ci.yml", + /ruby-version: "([\d.]+)"/ => RubyVersions.latest) + replace_in_file( + ".github/workflows/ci.yml", + /ruby-version: (\[(?:"[\d.]+"(?:, )?)*\])/ => + RubyVersions.latest_supported_minors.to_s) + end + + desc "Update year to current in LICENSE.txt" + task :year do + replace_in_file("LICENSE.txt", /\(c\) (\d+)/ => Date.today.year.to_s) + end +end + +def replace_in_file(path, replacements) + file_contents = File.read(path) + original_file_contents = file_contents.dup + + replacements.each do |regex, text| + raise "Can't find #{regex} in #{path}" unless regex.match?(file_contents) + + file_contents.gsub!(regex) do |match| + match[regex, 1] = text + match + end + end + + File.write(path, file_contents) if file_contents != original_file_contents +end + +# RubyVersions extracts current Ruby versions info from +# https://raw.githubusercontent.com/ruby/www.ruby-lang.org/HEAD/_data/downloads.yml +# -- which specifies the Ruby releases that will be listed on +# https://www.ruby-lang.org/en/downloads/ +module RubyVersions + MINOR_VERSION_REGEX = /\d+\.\d+/ + RUBY_VERSIONS_YAML_PATH = + "https://raw.githubusercontent.com/ruby/www.ruby-lang.org/HEAD/_data/downloads.yml" + VERSION_TYPES = %i[ + security_maintenance + stable + ].freeze + + def self.latest + latest_supported_patches.last + end + + def self.latest_supported_minors + latest_supported_patches.map { |version_string| + version_string[MINOR_VERSION_REGEX] + } + end + + def self.latest_supported_patches + @latest_supported_patches ||= begin + patches = + versions.fetch_values(*VERSION_TYPES).tap(&:flatten!).tap(&:compact!) + patches.map { |patch| Gem::Version.new(patch) }.sort!.map(&:to_s) + end + end + + def self.lowest_supported_minor + latest_supported_patches.first[MINOR_VERSION_REGEX] + end + + private + + def self.versions + @versions ||= begin + raw_yaml = URI.parse(RUBY_VERSIONS_YAML_PATH).open + YAML.safe_load(raw_yaml, symbolize_names: true) + end + end + private_class_method :versions +end