diff --git a/.github/workflows/release-rubygem.yaml b/.github/workflows/release-rubygem.yaml index 301a923a..d6932f1a 100644 --- a/.github/workflows/release-rubygem.yaml +++ b/.github/workflows/release-rubygem.yaml @@ -23,6 +23,10 @@ jobs: with: ruby-version: 4.0.6 working-directory: ruby + - name: Synchronize CiEnvironments.json + working-directory: ruby + run: bundle exec rake ci_environments + - run: ./scripts/fail-if-dirty - uses: rubygems/configure-rubygems-credentials@dc5a8d8553e6ee01fc26761a49e99e733d17954a # v2.1.0 - uses: cucumber/action-publish-rubygem@4e79bb9aed597c835e8438f57c04d0996ab80d72 # v2.0.0 with: diff --git a/.github/workflows/test-ruby.yaml b/.github/workflows/test-ruby.yaml index 46710276..610cc707 100644 --- a/.github/workflows/test-ruby.yaml +++ b/.github/workflows/test-ruby.yaml @@ -28,12 +28,12 @@ jobs: fail-fast: true matrix: os: [ubuntu-latest] - ruby: ['3.2', '3.3', '3.4', '3.5'] + ruby: ['3.2', '3.3', '3.4', '4.0'] include: - os: windows-latest - ruby: '3.4' + ruby: '4.0' - os: macos-latest - ruby: '3.4' + ruby: '4.0' steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: diff --git a/CHANGELOG.md b/CHANGELOG.md index 723d4b76..103c2741 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Fixed +- [Ruby] Ensure `CiEnvironments.json` is published (in new dir), in gem package +- BREAKING CHANGE: [Ruby] change `VariableExpression` module namespace to be top level alongside `CiEnvironment` module ## [14.0.0] - 2026-06-11 ### Changed diff --git a/ruby/.gitignore b/ruby/.gitignore index 5e7eec9f..463c834f 100644 --- a/ruby/.gitignore +++ b/ruby/.gitignore @@ -3,7 +3,6 @@ coverage/ pkg/ *.gem .compared -.deps -.tested* +lib/cucumber/CiEnvironments.json *-go *.iml diff --git a/ruby/.rubocop_todo.yml b/ruby/.rubocop_todo.yml index bdf91a04..1fa9bf2e 100644 --- a/ruby/.rubocop_todo.yml +++ b/ruby/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2025-10-07 17:03:37 UTC using RuboCop version 1.81.1. +# on 2026-07-22 07:32:12 UTC using RuboCop version 1.81.1. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -9,19 +9,14 @@ # TODO: Oct '23 -> 10 files inspected, 63 offenses detected, 53 offenses autocorrectable # TODO: Nov '24 -> 9 files inspected, 4 offenses detected, 0 offenses autocorrectable # TODO: Oct '25 -> 9 files inspected, 5 offenses detected, 1 offenses autocorrectable +# TODO: Jul '26 -> 7 files inspected, 2 offenses detected # Offense count: 1 -# This cop supports safe autocorrection (--autocorrect). -Layout/EmptyLinesAfterModuleInclusion: - Exclude: - - 'lib/cucumber/ci_environment.rb' - -# Offense count: 2 # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes. Metrics/AbcSize: Max: 22 -# Offense count: 2 +# Offense count: 1 # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns. Metrics/MethodLength: - Max: 23 + Max: 21 diff --git a/ruby/Rakefile b/ruby/Rakefile index e00ae19c..6341b384 100644 --- a/ruby/Rakefile +++ b/ruby/Rakefile @@ -3,7 +3,7 @@ $LOAD_PATH.unshift(File.expand_path('lib', __dir__)) file :ci_environments do - FileUtils.cp('../CiEnvironments.json', 'lib/cucumber/ci_environment/CiEnvironments.json') + FileUtils.cp('../CiEnvironments.json', 'lib/cucumber/CiEnvironments.json') end desc 'Copy the sample environments & run all the unit tests for all environment types' diff --git a/ruby/cucumber-ci-environment.gemspec b/ruby/cucumber-ci-environment.gemspec index 91bb3985..333aa3cb 100644 --- a/ruby/cucumber-ci-environment.gemspec +++ b/ruby/cucumber-ci-environment.gemspec @@ -5,7 +5,7 @@ version = File.read(File.expand_path('VERSION', __dir__)).strip Gem::Specification.new do |s| s.name = 'cucumber-ci-environment' s.version = version - s.authors = ['Vincent PrĂȘtre'] + s.authors = ['Vincent PrĂȘtre', 'Luke Hill'] s.description = 'Detect CI Environment from environment variables' s.summary = "#{s.name}-#{s.version}" s.email = 'cukes@googlegroups.com' diff --git a/ruby/lib/cucumber/ci_environment.rb b/ruby/lib/cucumber/ci_environment.rb index 8a768859..f713bb59 100644 --- a/ruby/lib/cucumber/ci_environment.rb +++ b/ruby/lib/cucumber/ci_environment.rb @@ -2,79 +2,78 @@ require 'uri' require 'json' -require 'cucumber/ci_environment/variable_expression' +require 'cucumber/variable_expression' module Cucumber - module CiEnvironment + class CiEnvironment extend VariableExpression - CI_ENVIRONMENTS_PATH = File.join(File.dirname(__FILE__), 'ci_environment/CiEnvironments.json') - module_function + CI_ENVIRONMENTS_PATH = File.join(File.dirname(__FILE__), './CiEnvironments.json') - def detect_ci_environment(env) - ci_environments = JSON.parse(File.read(CI_ENVIRONMENTS_PATH)) - ci_environments.each do |ci_environment| - detected = detect(ci_environment, env) - return detected unless detected.nil? - end - - nil - end + class << self + def detect_ci_environment(env) + ci_environments = JSON.parse(File.read(CI_ENVIRONMENTS_PATH)) + ci_environments.each do |ci_environment| + detected = detect(ci_environment, env) + return detected unless detected.nil? + end - def detect(ci_environment, env) - url = evaluate(ci_environment['url'], env) - return nil if url.nil? + nil + end - result = { - name: ci_environment['name'], - url: url, - buildNumber: evaluate(ci_environment['buildNumber'], env) - } + def remove_userinfo_from_url(value) + return nil if value.nil? - detected_git = detect_git(ci_environment, env) - result[:git] = detected_git if detected_git - result - end + begin + uri = URI(value) + uri.userinfo = '' + uri.to_s + rescue StandardError + value + end + end - def detect_git(ci_environment, env) - revision = detect_revision(ci_environment, env) - return nil if revision.nil? + private - remote = evaluate(ci_environment['git']['remote'], env) - return nil if remote.nil? + def detect(ci_environment, env) + url = evaluate(ci_environment['url'], env) + return nil if url.nil? - git_info = { - remote: remove_userinfo_from_url(remote), - revision: revision - } + result = { + name: ci_environment['name'], + url: url, + buildNumber: evaluate(ci_environment['buildNumber'], env) + } - tag = evaluate(ci_environment['git']['tag'], env) - branch = evaluate(ci_environment['git']['branch'], env) - git_info[:tag] = tag if tag - git_info[:branch] = branch if branch - git_info - end + detected_git = detect_git(ci_environment, env) + result[:git] = detected_git if detected_git + result + end - def detect_revision(ci_environment, env) - return evaluate(ci_environment['git']['revision'], env) unless env['GITHUB_EVENT_NAME'] == 'pull_request' + def detect_git(ci_environment, env) + revision = detect_revision(ci_environment, env) + return nil if revision.nil? - raise StandardError('GITHUB_EVENT_PATH not set') unless env['GITHUB_EVENT_PATH'] + remote = evaluate(ci_environment['git']['remote'], env) + return nil if remote.nil? - event = JSON.parse(File.read(env['GITHUB_EVENT_PATH'])) - event.dig('pull_request', 'head', 'sha').tap do |revision| - raise StandardError("Could not find .pull_request.head.sha in GITHUB_EVENT_PATH:\n#{JSON.pretty_generate(event)}") if revision.nil? + { + remote: remove_userinfo_from_url(remote), + revision: revision, + tag: evaluate(ci_environment['git']['tag'], env), + branch: evaluate(ci_environment['git']['branch'], env) + }.compact end - end - def remove_userinfo_from_url(value) - return nil if value.nil? + def detect_revision(ci_environment, env) + return evaluate(ci_environment['git']['revision'], env) unless env['GITHUB_EVENT_NAME'] == 'pull_request' + + raise StandardError('GITHUB_EVENT_PATH not set') unless env['GITHUB_EVENT_PATH'] - begin - uri = URI(value) - uri.userinfo = '' - uri.to_s - rescue StandardError - value + event = JSON.parse(File.read(env['GITHUB_EVENT_PATH'])) + event.dig('pull_request', 'head', 'sha').tap do |revision| + raise StandardError("Could not find .pull_request.head.sha in GITHUB_EVENT_PATH:\n#{JSON.pretty_generate(event)}") if revision.nil? + end end end end diff --git a/ruby/lib/cucumber/ci_environment/.gitignore b/ruby/lib/cucumber/ci_environment/.gitignore deleted file mode 100644 index ab44ddb1..00000000 --- a/ruby/lib/cucumber/ci_environment/.gitignore +++ /dev/null @@ -1 +0,0 @@ -CiEnvironments.json diff --git a/ruby/lib/cucumber/ci_environment/variable_expression.rb b/ruby/lib/cucumber/ci_environment/variable_expression.rb deleted file mode 100644 index dadf80a2..00000000 --- a/ruby/lib/cucumber/ci_environment/variable_expression.rb +++ /dev/null @@ -1,49 +0,0 @@ -# frozen_string_literal: true - -module Cucumber - module CiEnvironment - module VariableExpression - def evaluate(expression, env) - return nil if expression.nil? - - begin - expression.gsub(/\${(.*?)(?:(?