diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 24cb1f3..8062b7f 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -98,7 +98,7 @@ jobs: hide_complexity: true indicators: true output: both - thresholds: '69 80' + thresholds: '100 100' continue-on-error: ${{ matrix.experimental != 'false' }} - name: Add Coverage PR Comment @@ -109,13 +109,22 @@ jobs: path: code-coverage-results.md continue-on-error: ${{ matrix.experimental != 'false' }} - - name: Coveralls + - name: Upload coverage to Coveralls uses: coverallsapp/github-action@master with: github-token: ${{ secrets.GITHUB_TOKEN }} continue-on-error: ${{ matrix.experimental != 'false' }} - - name: Upload results to Codecov + - name: Upload coverage to QLTY + uses: qltysh/qlty-action/coverage@main + with: + coverage-token: ${{secrets.QLTY_COVERAGE_TOKEN}} + files: coverage/.resultset.json + continue-on-error: ${{ matrix.experimental != 'false' }} + + - name: Upload coverage to CodeCov uses: codecov/codecov-action@v5 with: + fail_ci_if_error: true # optional (default = false) token: ${{ secrets.CODECOV_TOKEN }} + verbose: true # optional (default = false) diff --git a/.github/workflows/current.yml b/.github/workflows/current.yml index a7273b9..d499ccc 100644 --- a/.github/workflows/current.yml +++ b/.github/workflows/current.yml @@ -54,7 +54,7 @@ jobs: rubygems: default bundler: default - # jruby-9.4 (targets Ruby 3.1 compatibility) + # jruby-10.0 (targets Ruby 3.4 compatibility) - ruby: "jruby" appraisal: "current" exec_cmd: "rake spec" diff --git a/.github/workflows/hoary.yml b/.github/workflows/hoary.yml deleted file mode 100644 index 3249c43..0000000 --- a/.github/workflows/hoary.yml +++ /dev/null @@ -1,62 +0,0 @@ -# NOTE: Hoary is a synonym of ancient -name: MRI 2.2 (EOL) - -on: - push: - branches: - - 'main' - tags: - - '!*' # Do not execute on tags - pull_request: - branches: - - '*' - # Allow manually triggering the workflow. - workflow_dispatch: - -# Cancels all previous workflow runs for the same branch that have not yet completed. -concurrency: - # The concurrency group contains the workflow name and the branch name. - group: "${{ github.workflow }}-${{ github.ref }}" - cancel-in-progress: true - -jobs: - test: - name: Specs ${{ matrix.ruby }} ${{ matrix.appraisal }}${{ matrix.name_extra || '' }} - if: "!contains(github.event.commits[0].message, '[ci skip]') && !contains(github.event.commits[0].message, '[skip ci]')" - runs-on: ubuntu-20.04 - continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }} - env: # $BUNDLE_GEMFILE must be set at job level, so it is set for all steps - BUNDLE_GEMFILE: ${{ github.workspace }}/${{ matrix.gemfile }}.gemfile - strategy: - fail-fast: false - matrix: - include: - # Ruby 2.2 - - ruby: "ruby-2.2" - appraisal: "ruby-2-2" - exec_cmd: "rake spec" - gemfile: "Appraisal.root" - rubygems: default - bundler: default - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup Ruby & RubyGems - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ matrix.ruby }} - rubygems: ${{ matrix.rubygems }} - bundler: ${{ matrix.bundler }} - bundler-cache: false - - # Raw `bundle` will use the BUNDLE_GEMFILE set to matrix.gemfile (i.e. Appraisal.root) - # We need to do this first to get appraisal installed. - # NOTE: This does not use the main Gemfile at all. - - name: Install Root Appraisal - run: bundle - - name: Appraisal for ${{ matrix.appraisal }} - run: bundle exec appraisal ${{ matrix.appraisal }} bundle - - name: Tests for ${{ matrix.ruby }} via ${{ matrix.exec_cmd }} - run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec ${{ matrix.exec_cmd }} diff --git a/Appraisals b/Appraisals index 7f405cf..1e3ce84 100644 --- a/Appraisals +++ b/Appraisals @@ -72,6 +72,12 @@ appraise "ruby-3-3" do remove_gem "appraisal" # only present because it must be in the gemfile because we target a git branch end +appraise "ruby-3-4" do + gem "mutex_m", "~> 0.2" + gem "stringio", "~> 3.0" + remove_gem "appraisal" # only present because it must be in the gemfile because we target a git branch +end + # Only run security audit on latest Ruby version appraise "audit" do gem "mutex_m", "~> 0.2" diff --git a/README.md b/README.md index d92c0f4..ce99f18 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ This gem has a very niche purpose, which is: 3. allowing 100% test coverage of Ruby code, including the `Version` module. As proof in the pudding, this gem achieves 100% test coverage for lines and branches, -all 77 and 2 of them, respectively; coverage enabled in part by patterns from this library. +all 117 and 4 of them, respectively; coverage enabled in part by patterns from this library. You can make it happen for your library too! If this isn't **precisely** your use case you may be better off looking at @@ -70,10 +70,10 @@ This gem has no runtime dependencies. | Tokens to Remember | [![Gem name][⛳️name-img]][⛳️gem-name] [![Gem namespace][⛳️namespace-img]][⛳️gem-namespace] | |-------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| Works with JRuby | [![JRuby 9.1 Compat][💎jruby-9.1i]][🚎10-j-wf] [![JRuby 9.2 Compat][💎jruby-9.2i]][🚎10-j-wf] [![JRuby 9.3 Compat][💎jruby-9.3i]][🚎10-j-wf] [![JRuby 9.4 Compat][💎jruby-c-i]][🚎11-c-wf] [![JRuby HEAD Compat][💎jruby-headi]][🚎3-hd-wf] | +| Works with JRuby | [![JRuby 9.1 Compat][💎jruby-9.1i]][🚎10-j-wf] [![JRuby 9.2 Compat][💎jruby-9.2i]][🚎10-j-wf] [![JRuby 9.3 Compat][💎jruby-9.3i]][🚎10-j-wf] [![JRuby 9.4 Compat][💎jruby-9.4i]][🚎10-j-wf] [![JRuby 10.0 Compat][💎jruby-c-i]][🚎11-c-wf] [![JRuby HEAD Compat][💎jruby-headi]][🚎3-hd-wf] | | Works with Truffle Ruby | [![Truffle Ruby 22.3 Compat][💎truby-22.3i]][🚎9-t-wf] [![Truffle Ruby 23.0 Compat][💎truby-23.0i]][🚎9-t-wf] [![Truffle Ruby 23.1 Compat][💎truby-23.1i]][🚎9-t-wf] [![Truffle Ruby 24.1 Compat][💎truby-c-i]][🚎11-c-wf] [![Truffle Ruby HEAD Compat][💎truby-headi]][🚎3-hd-wf] | | Works with MRI Ruby 3 | [![Ruby 3.0 Compat][💎ruby-3.0i]][🚎4-lg-wf] [![Ruby 3.1 Compat][💎ruby-3.1i]][🚎6-s-wf] [![Ruby 3.2 Compat][💎ruby-3.2i]][🚎6-s-wf] [![Ruby 3.3 Compat][💎ruby-3.3i]][🚎6-s-wf] [![Ruby 3.4 Compat][💎ruby-c-i]][🚎11-c-wf] [![Ruby HEAD Compat][💎ruby-headi]][🚎3-hd-wf] | -| Works with MRI Ruby 2 | [![Ruby 2.2 Compat][💎ruby-2.2i]][🚎8-ho-wf] [![Ruby 2.3 Compat][💎ruby-2.3i]][🚎1-an-wf] [![Ruby 2.4 Compat][💎ruby-2.4i]][🚎1-an-wf] [![Ruby 2.5 Compat][💎ruby-2.5i]][🚎1-an-wf] [![Ruby 2.6 Compat][💎ruby-2.6i]][🚎7-us-wf] [![Ruby 2.7 Compat][💎ruby-2.7i]][🚎7-us-wf] | +| Works with MRI Ruby 2 | [![Ruby 2.3 Compat][💎ruby-2.3i]][🚎1-an-wf] [![Ruby 2.4 Compat][💎ruby-2.4i]][🚎1-an-wf] [![Ruby 2.5 Compat][💎ruby-2.5i]][🚎1-an-wf] [![Ruby 2.6 Compat][💎ruby-2.6i]][🚎7-us-wf] [![Ruby 2.7 Compat][💎ruby-2.7i]][🚎7-us-wf] | | Source | [![Source on GitLab.com][📜src-gl-img]][📜src-gl] [![Source on Github.com][📜src-gh-img]][📜src-gh] [![The best SHA: dQw4w9WgXcQ!][🧮kloc-img]][🧮kloc] | | Documentation | [![Current release on RubyDoc.info][📜docs-cr-rd-img]][🚎yard-current] [![HEAD on RubyDoc.info][📜docs-head-rd-img]][🚎yard-head] [![BDFL Blog][🚂bdfl-blog-img]][🚂bdfl-blog] [![Wiki][📜wiki-img]][📜wiki] | | Compliance | [![License: MIT][📄license-img]][📄license-ref] [![📄ilo-declaration-img]][📄ilo-declaration] [![Security Policy][🔐security-img]][🔐security] [![CodeQL][🖐codeQL-img]][🖐codeQL] [![Contributor Covenant 2.1][🪇conduct-img]][🪇conduct] [![SemVer 2.0.0][📌semver-img]][📌semver] [![Keep-A-Changelog 1.0.0][📗keep-changelog-img]][📗keep-changelog] | @@ -162,7 +162,7 @@ end Your `version.rb` file now abides the Ruby convention of directory / path matching the namespace / class! -## Epoch Usage (Epoch Semantic Versioning) +## Epoch Usage (Epoch Semantic Versioning, as of version 1.1.7) In the standard `bundle gem my_lib` code you get the following in `lib/my_lib/version.rb`: @@ -177,11 +177,52 @@ Change it to a nested `Version` namespace (the one implied by the path => namesp ```ruby module MyLib module Version - VERSION = "1024.3.8" + VERSION = "0.1.0" end end ``` +The Epoch and Major versions are derived from the formula: + +``` +{EPOCH * 1000 + MAJOR}.MINOR.PATCH +``` + +This will start your library with the following version segments: + +* `epoch = 0` +* `major = 0` +* `minor = 1` +* `patch = 0` +* `pre = nil` + +And the segments are defined as: + +``` +EPOCH: Increment when you make significant or groundbreaking changes. +MAJOR: Increment when you make minor incompatible API changes. +MINOR: Increment when you add functionality in a backwards-compatible manner. +PATCH: Increment when you make backwards-compatible bug fixes. +``` + +Therefore, if you set your version number to: + +```ruby +VERSION = "27016.42.86-pre.7" +``` + +You will get the following version segments: + +``` +{ + epoch: 27, + major: 16, + minor: 42, + patch: 86, + pre: "pre-7", +} +``` + Now add the following near the top of the file the manages requiring external libraries. Using the same example of `bundle gem my_lib`, this would be `lib/my_lib.rb`. @@ -308,9 +349,11 @@ RSpec.describe(MyLib::Version) do expect(described_class).to(have_version_as_string) expect(described_class.to_s).to(be_a(String)) expect(described_class).to(have_major_as_integer) + expect(described_class).to(have_epoch_as_integer) expect(described_class).to(have_minor_as_integer) expect(described_class).to(have_patch_as_integer) expect(described_class).to(have_pre_as_nil_or_string) + # This would be %i[epoch major minor patch pre] for epoch version schemes expect(described_class.to_h.keys).to(match_array(%i[major minor patch pre])) expect(described_class.to_a).to(be_a(Array)) end @@ -364,7 +407,8 @@ This Library adheres to [![Epoch Semantic Versioning][📌semver-img]][📌semve Violations of this scheme should be reported as bugs. Specifically, if a minor or patch version is released that breaks backward compatibility, a new version should be immediately released that restores compatibility. -Breaking changes to the public API, including dropping a supported platform (i.e. minor version of Ruby), will only be introduced with new major versions. +Breaking changes to the public API, including dropping a supported platform (i.e. minor version of Ruby), +will only be introduced with new major versions. Epoch will only be bumped if there are dramatic changes, and that is not expected to happen ever. ### 📌 Is "Platform Support" part of the public API? @@ -475,10 +519,10 @@ or one of the others at the head of this README. [👽oss-helpi]: https://www.codetriage.com/oauth-xx/version_gem/badges/users.svg [👽version]: https://rubygems.org/gems/version_gem [👽versioni]: https://img.shields.io/gem/v/version_gem.svg -[🔑cc-mnt]: https://codeclimate.com/github/oauth-xx/version_gem/maintainability -[🔑cc-mnti♻️]: https://api.codeclimate.com/v1/badges/e26c543320ca0d14e871/maintainability -[🔑cc-cov]: https://codeclimate.com/github/oauth-xx/version_gem/test_coverage -[🔑cc-covi♻️]: https://api.codeclimate.com/v1/badges/e26c543320ca0d14e871/test_coverage +[🔑cc-mnt]: https://qlty.sh/gh/rubocop-lts/projects/standard-rubocop-lts +[🔑cc-mnti♻️]: https://qlty.sh/badges/19404e90-9168-451a-8dac-882382cb768d/maintainability.svg +[🔑cc-cov]: https://qlty.sh/gh/rubocop-lts/projects/standard-rubocop-lts +[🔑cc-covi♻️]: https://qlty.sh/badges/19404e90-9168-451a-8dac-882382cb768d/test_coverage.svg [🔑codecov]: https://codecov.io/gh/oauth-xx/version_gem [🔑codecovi♻️]: https://codecov.io/gh/oauth-xx/version_gem/branch/main/graph/badge.svg?token=cc6UdZCpAL [🔑coveralls]: https://coveralls.io/github/oauth-xx/version_gem?branch=main @@ -501,8 +545,6 @@ or one of the others at the head of this README. [🚎6-s-wfi]: https://github.com/oauth-xx/version_gem/actions/workflows/supported.yml/badge.svg [🚎7-us-wf]: https://github.com/oauth-xx/version_gem/actions/workflows/unsupported.yml [🚎7-us-wfi]: https://github.com/oauth-xx/version_gem/actions/workflows/unsupported.yml/badge.svg -[🚎8-ho-wf]: https://github.com/oauth-xx/version_gem/actions/workflows/hoary.yml -[🚎8-ho-wfi]: https://github.com/oauth-xx/version_gem/actions/workflows/hoary.yml/badge.svg [🚎9-t-wf]: https://github.com/oauth-xx/version_gem/actions/workflows/truffle.yml [🚎9-t-wfi]: https://github.com/oauth-xx/version_gem/actions/workflows/truffle.yml/badge.svg [🚎10-j-wf]: https://github.com/oauth-xx/version_gem/actions/workflows/jruby.yml @@ -522,7 +564,6 @@ or one of the others at the head of this README. [🖇buyme-img]: https://img.buymeacoffee.com/button-api/?text=Buy%20me%20a%20latte&emoji=&slug=pboling&button_colour=FFDD00&font_colour=000000&font_family=Cookie&outline_colour=000000&coffee_colour=ffffff [🖇buyme]: https://www.buymeacoffee.com/pboling [🖇buyme-small-img]: https://img.shields.io/badge/buy_me_a_coffee-✓-yellow.svg?style=flat -[💎ruby-2.2i]: https://img.shields.io/badge/Ruby-2.2-DF00CA?style=for-the-badge&logo=ruby&logoColor=white [💎ruby-2.3i]: https://img.shields.io/badge/Ruby-2.3-DF00CA?style=for-the-badge&logo=ruby&logoColor=white [💎ruby-2.4i]: https://img.shields.io/badge/Ruby-2.4-DF00CA?style=for-the-badge&logo=ruby&logoColor=white [💎ruby-2.5i]: https://img.shields.io/badge/Ruby-2.5-DF00CA?style=for-the-badge&logo=ruby&logoColor=white @@ -542,6 +583,7 @@ or one of the others at the head of this README. [💎jruby-9.1i]: https://img.shields.io/badge/JRuby-9.1-FBE742?style=for-the-badge&logo=ruby&logoColor=red [💎jruby-9.2i]: https://img.shields.io/badge/JRuby-9.2-FBE742?style=for-the-badge&logo=ruby&logoColor=red [💎jruby-9.3i]: https://img.shields.io/badge/JRuby-9.3-FBE742?style=for-the-badge&logo=ruby&logoColor=red +[💎jruby-9.4i]: https://img.shields.io/badge/JRuby-9.4-FBE742?style=for-the-badge&logo=ruby&logoColor=red [💎jruby-c-i]: https://img.shields.io/badge/JRuby-current-FBE742?style=for-the-badge&logo=ruby&logoColor=green [💎jruby-headi]: https://img.shields.io/badge/JRuby-HEAD-FBE742?style=for-the-badge&logo=ruby&logoColor=blue [🤝issues]: https://github.com/oauth-xx/version_gem/issues @@ -563,7 +605,7 @@ or one of the others at the head of this README. [📗keep-changelog]: https://keepachangelog.com/en/1.0.0/ [📗keep-changelog-img]: https://img.shields.io/badge/keep--a--changelog-1.0.0-FFDD67.svg?style=flat [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ -[🧮kloc-img]: https://img.shields.io/badge/KLOC-0.077-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue +[🧮kloc-img]: https://img.shields.io/badge/KLOC-0.117-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue [🔐security]: SECURITY.md [🔐security-img]: https://img.shields.io/badge/security-policy-brightgreen.svg?style=flat [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year diff --git a/gemfiles/ruby_3_4.gemfile b/gemfiles/ruby_3_4.gemfile new file mode 100644 index 0000000..ed1eb63 --- /dev/null +++ b/gemfiles/ruby_3_4.gemfile @@ -0,0 +1,8 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "mutex_m", "~> 0.2" +gem "stringio", "~> 3.0" + +gemspec path: "../"