diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..28a19d2 Binary files /dev/null and b/.DS_Store differ diff --git a/.github/workflows/pr-title-lint.yml b/.github/workflows/pr-title-lint.yml index d2c4216..8ed6c4b 100644 --- a/.github/workflows/pr-title-lint.yml +++ b/.github/workflows/pr-title-lint.yml @@ -1,4 +1,4 @@ -name: "Lint PR" +name: 'Lint PR' on: pull_request_target: @@ -12,6 +12,29 @@ jobs: name: Validate PR title runs-on: ubuntu-latest steps: - - uses: amannn/action-semantic-pull-request@v5 + - uses: amannn/action-semantic-pull-request@e9fabac35e210fea40ca5b14c0da95a099eff26f # v5 + id: lint_pr_title env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - uses: marocchino/sticky-pull-request-comment@331f8f5b4215f0445d3c07b4967662a32a2d3e31 # v2 + # When the previous steps fails, the workflow would stop. By adding this + # condition you can continue the execution with the populated error message. + if: always() && (steps.lint_pr_title.outputs.error_message != null) + with: + header: pr-title-lint-error + message: | + Hey there and thank you for opening this pull request! ๐Ÿ‘‹๐Ÿผ + + We require pull request titles to follow the [Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0/) and it looks like your proposed title needs to be adjusted. + Details: + + ``` + ${{ steps.lint_pr_title.outputs.error_message }} + ``` + # Delete a previous comment when the issue has been resolved + - if: ${{ steps.lint_pr_title.outputs.error_message == null }} + uses: marocchino/sticky-pull-request-comment@331f8f5b4215f0445d3c07b4967662a32a2d3e31 # v2 + with: + header: pr-title-lint-error + delete: true \ No newline at end of file diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml new file mode 100644 index 0000000..756a8b5 --- /dev/null +++ b/.github/workflows/release-please.yml @@ -0,0 +1,59 @@ +name: Release Please + +on: + push: + branches: + - main + +jobs: + release-please: + name: Release Please + runs-on: ubuntu-latest + # Release-please creates a PR that tracks all changes + steps: + - uses: google-github-actions/release-please-action@v3 + id: release + with: + release-type: ruby + command: manifest + token: ${{ secrets.RELEASE_PLEASE_ACTION_TOKEN }} + default-branch: main + signoff: "OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com>" + + - name: Dump Release Please Output + env: + RELEASE_PLEASE_OUTPUT: ${{ toJson(steps.release.outputs) }} + run: | + echo "$RELEASE_PLEASE_OUTPUT" + + outputs: + all: ${{ toJSON(steps.release.outputs) }} + paths_released: ${{ steps.release.outputs.paths_released }} + + publish-gems: + name: Publish Ruby Gems + needs: release-please + runs-on: ubuntu-latest + if: ${{ fromJSON(needs.release-please.outputs.paths_released)[0] != null }} + strategy: + matrix: + path: ${{ fromJSON(needs.release-please.outputs.paths_released) }} + env: + TAG: ${{ fromJSON(needs.release-please.outputs.all)[format('{0}--tag_name', matrix.path)] }} + defaults: + run: + working-directory: ./${{ matrix.path }} + steps: + - name: Checkout + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + with: + ref: ${{ env.TAG }} + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + # TODO see if the ruby version matter for publishing + # ruby-version: ${{ matrix.ruby-version }} + bundler-cache: true # runs 'bundle install' and caches installed gems automatically + + ## TODO add a step to publish the gem diff --git a/.github/workflows/ruby.yml b/.github/workflows/ruby.yml index 9668cd3..3de104a 100644 --- a/.github/workflows/ruby.yml +++ b/.github/workflows/ruby.yml @@ -47,7 +47,7 @@ jobs: runs-on: ubuntu-latest defaults: run: - working-directory: ./providers/openfeature-sdk-meta_provider + working-directory: ./providers/openfeature-meta_provider strategy: matrix: ruby-version: @@ -61,6 +61,6 @@ jobs: with: ruby-version: ${{ matrix.ruby-version }} bundler-cache: true # runs 'bundle install' and caches installed gems automatically - working-directory: ./providers/openfeature-sdk-meta_provider + working-directory: ./providers/openfeature-meta_provider - name: Lint and test run: bin/rake diff --git a/.release-please-manifest.json b/.release-please-manifest.json new file mode 100644 index 0000000..e25325a --- /dev/null +++ b/.release-please-manifest.json @@ -0,0 +1,4 @@ +{ + "providers/openfeature-flagd-provider": "0.0.1", + "providers/openfeature-meta_provider": "0.0.1" +} diff --git a/providers/.DS_Store b/providers/.DS_Store new file mode 100644 index 0000000..badc986 Binary files /dev/null and b/providers/.DS_Store differ diff --git a/providers/openfeature-flagd-provider/README.md b/providers/openfeature-flagd-provider/README.md index ab5ea6f..57b8b43 100644 --- a/providers/openfeature-flagd-provider/README.md +++ b/providers/openfeature-flagd-provider/README.md @@ -1,6 +1,7 @@ # OpenFeature FlagD Provider for Ruby This is the Ruby [provider](https://openfeature.dev/docs/specification/sections/providers) implementation of the [FlagD](https://github.com/open-feature/flagd) + ## Installation Add this line to your application's Gemfile: @@ -75,7 +76,6 @@ OpenFeature::SDK.configure do |config| end ``` - If no environment variables are set the [default configuration](./lib/openfeature/flagd/provider/configuration.rb) is set ## Contributing diff --git a/providers/openfeature-flagd-provider/lib/openfeature/flagd/provider.rb b/providers/openfeature-flagd-provider/lib/openfeature/flagd/provider.rb index cef1f2a..23d84ec 100644 --- a/providers/openfeature-flagd-provider/lib/openfeature/flagd/provider.rb +++ b/providers/openfeature-flagd-provider/lib/openfeature/flagd/provider.rb @@ -4,6 +4,7 @@ require_relative "provider/configuration" require_relative "provider/client" +require_relative "provider/version" module OpenFeature module FlagD diff --git a/providers/openfeature-flagd-provider/lib/openfeature/flagd/provider/version.rb b/providers/openfeature-flagd-provider/lib/openfeature/flagd/provider/version.rb new file mode 100644 index 0000000..99ab24c --- /dev/null +++ b/providers/openfeature-flagd-provider/lib/openfeature/flagd/provider/version.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module OpenFeature + module FlagD + VERSION = "0.0.1" + end +end diff --git a/providers/openfeature-flagd-provider/openfeature-flagd-provider.gemspec b/providers/openfeature-flagd-provider/openfeature-flagd-provider.gemspec index 28f7ab7..50ba9fe 100644 --- a/providers/openfeature-flagd-provider/openfeature-flagd-provider.gemspec +++ b/providers/openfeature-flagd-provider/openfeature-flagd-provider.gemspec @@ -1,8 +1,10 @@ # frozen_string_literal: true +require_relative "lib/openfeature/flagd/provider/version" + Gem::Specification.new do |spec| spec.name = "openfeature-flagd-provider" - spec.version = "0.0.1" + spec.version = OpenFeature::FlagD::VERSION spec.authors = ["OpenFeature Authors"] spec.email = ["cncf-openfeature-contributors@lists.cncf.io"] @@ -14,7 +16,7 @@ Gem::Specification.new do |spec| spec.metadata["homepage_uri"] = spec.homepage spec.metadata["source_code_uri"] = "https://github.com/open-feature/ruby-sdk-contrib/providers/openfeature-flagd-provider" - spec.metadata["changelog_uri"] = "https://github.com/open-feature/ruby-sdk-contrib/blob/main/CHANGELOG.md" + spec.metadata["changelog_uri"] = "https://github.com/open-feature/ruby-sdk-contrib/blob/main/providers/openfeature-flagd-provider/CHANGELOG.md" spec.metadata["bug_tracker_uri"] = "https://github.com/open-feature/ruby-sdk-contrib/issues" spec.metadata["documentation_uri"] = "https://github.com/open-feature/ruby-sdk-contrib/README.md" diff --git a/providers/openfeature-sdk-meta_provider/.gitignore b/providers/openfeature-meta_provider/.gitignore similarity index 100% rename from providers/openfeature-sdk-meta_provider/.gitignore rename to providers/openfeature-meta_provider/.gitignore diff --git a/providers/openfeature-sdk-meta_provider/.rspec b/providers/openfeature-meta_provider/.rspec similarity index 100% rename from providers/openfeature-sdk-meta_provider/.rspec rename to providers/openfeature-meta_provider/.rspec diff --git a/providers/openfeature-sdk-meta_provider/.ruby-version b/providers/openfeature-meta_provider/.ruby-version similarity index 100% rename from providers/openfeature-sdk-meta_provider/.ruby-version rename to providers/openfeature-meta_provider/.ruby-version diff --git a/providers/openfeature-sdk-meta_provider/.standard.yml b/providers/openfeature-meta_provider/.standard.yml similarity index 100% rename from providers/openfeature-sdk-meta_provider/.standard.yml rename to providers/openfeature-meta_provider/.standard.yml diff --git a/providers/openfeature-sdk-meta_provider/.tool-versions b/providers/openfeature-meta_provider/.tool-versions similarity index 100% rename from providers/openfeature-sdk-meta_provider/.tool-versions rename to providers/openfeature-meta_provider/.tool-versions diff --git a/providers/openfeature-meta_provider/Gemfile b/providers/openfeature-meta_provider/Gemfile new file mode 100644 index 0000000..bf64f07 --- /dev/null +++ b/providers/openfeature-meta_provider/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +# Specify your gem's dependencies in openfeature-meta_provider.gemspec +gemspec diff --git a/providers/openfeature-sdk-meta_provider/Gemfile.lock b/providers/openfeature-meta_provider/Gemfile.lock similarity index 96% rename from providers/openfeature-sdk-meta_provider/Gemfile.lock rename to providers/openfeature-meta_provider/Gemfile.lock index 5412384..5ad1502 100644 --- a/providers/openfeature-sdk-meta_provider/Gemfile.lock +++ b/providers/openfeature-meta_provider/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - openfeature-sdk-meta_provider (0.1.0) + openfeature-meta_provider (0.0.1) openfeature-sdk (~> 0.3.0) GEM @@ -86,7 +86,7 @@ PLATFORMS DEPENDENCIES debug (~> 1.9.2) - openfeature-sdk-meta_provider! + openfeature-meta_provider! rake (~> 13.0) rspec (~> 3.12) standard (~> 1.34) diff --git a/providers/openfeature-sdk-meta_provider/README.md b/providers/openfeature-meta_provider/README.md similarity index 100% rename from providers/openfeature-sdk-meta_provider/README.md rename to providers/openfeature-meta_provider/README.md diff --git a/providers/openfeature-sdk-meta_provider/Rakefile b/providers/openfeature-meta_provider/Rakefile similarity index 100% rename from providers/openfeature-sdk-meta_provider/Rakefile rename to providers/openfeature-meta_provider/Rakefile diff --git a/providers/openfeature-sdk-meta_provider/bin/console b/providers/openfeature-meta_provider/bin/console similarity index 100% rename from providers/openfeature-sdk-meta_provider/bin/console rename to providers/openfeature-meta_provider/bin/console diff --git a/providers/openfeature-sdk-meta_provider/bin/rake b/providers/openfeature-meta_provider/bin/rake similarity index 100% rename from providers/openfeature-sdk-meta_provider/bin/rake rename to providers/openfeature-meta_provider/bin/rake diff --git a/providers/openfeature-sdk-meta_provider/bin/setup b/providers/openfeature-meta_provider/bin/setup similarity index 100% rename from providers/openfeature-sdk-meta_provider/bin/setup rename to providers/openfeature-meta_provider/bin/setup diff --git a/providers/openfeature-meta_provider/lib/openfeature/meta_provider.rb b/providers/openfeature-meta_provider/lib/openfeature/meta_provider.rb new file mode 100644 index 0000000..2360109 --- /dev/null +++ b/providers/openfeature-meta_provider/lib/openfeature/meta_provider.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +module OpenFeature + # Used to pull from multiple providers. + class MetaProvider + # @param providers [Array] + # @param strategy [Symbol] When `:first_match`, returns first matched resolution. Providers will be searched + # in the order they were given. Defaults to `:first_match`. + def initialize(providers:, strategy: :first_match) + @providers = providers + @strategy = strategy + end + + def metadata + SDK::Provider::ProviderMetadata.new(name: "MetaProvider: #{providers.map { |provider| provider.metadata.name }.join(", ")}") + end + + def init + providers.each { |provider| provider.init } + end + + def shutdown + providers.each(&:shutdown) + end + + def fetch_boolean_value(flag_key:, default_value:, evaluation_context: nil) + fetch_from_sources(default_value:) do |provider| + provider.fetch_boolean_value(flag_key:, default_value:, evaluation_context:) + end + end + + def fetch_number_value(flag_key:, default_value:, evaluation_context: nil) + fetch_from_sources(default_value:) do |provider| + provider.fetch_number_value(flag_key:, default_value:, evaluation_context:) + end + end + + def fetch_object_value(flag_key:, default_value:, evaluation_context: nil) + fetch_from_sources(default_value:) do |provider| + provider.fetch_object_value(flag_key:, default_value:, evaluation_context:) + end + end + + def fetch_string_value(flag_key:, default_value:, evaluation_context: nil) + fetch_from_sources(default_value:) do |provider| + provider.fetch_string_value(flag_key:, default_value:, evaluation_context:) + end + end + + private + + attr_reader :providers, :strategy + + def fetch_from_sources(default_value:, &blk) + case strategy + when :first_match + successful_details = providers.each do |provider| + details = yield(provider) + + break details if details.error_code.nil? + rescue + next + end + + if successful_details.is_a?(SDK::Provider::ResolutionDetails) + successful_details + else + SDK::Provider::ResolutionDetails.new(value: default_value, error_code: SDK::Provider::ErrorCode::GENERAL, reason: SDK::Provider::Reason::ERROR) + end + else + SDK::Provider::ResolutionDetails.new(value: default_value, error_code: SDK::Provider::ErrorCode::GENERAL, reason: "Unknown strategy for MetaProvider") + end + end + end +end diff --git a/providers/openfeature-meta_provider/lib/openfeature/meta_provider_version.rb b/providers/openfeature-meta_provider/lib/openfeature/meta_provider_version.rb new file mode 100644 index 0000000..fa7ae5f --- /dev/null +++ b/providers/openfeature-meta_provider/lib/openfeature/meta_provider_version.rb @@ -0,0 +1,3 @@ +module OpenFeature + META_PROVIDER_VERSION = "0.0.1" +end diff --git a/providers/openfeature-sdk-meta_provider/openfeature-sdk-meta_provider.gemspec b/providers/openfeature-meta_provider/openfeature-meta_provider.gemspec similarity index 82% rename from providers/openfeature-sdk-meta_provider/openfeature-sdk-meta_provider.gemspec rename to providers/openfeature-meta_provider/openfeature-meta_provider.gemspec index f590a1b..e15b934 100644 --- a/providers/openfeature-sdk-meta_provider/openfeature-sdk-meta_provider.gemspec +++ b/providers/openfeature-meta_provider/openfeature-meta_provider.gemspec @@ -1,20 +1,22 @@ # frozen_string_literal: true +require_relative "lib/openfeature/meta_provider_version" + Gem::Specification.new do |spec| - spec.name = "openfeature-sdk-meta_provider" - spec.version = "0.1.0" + spec.name = "openfeature-meta_provider" + spec.version = OpenFeature::META_PROVIDER_VERSION spec.authors = ["OpenFeature Authors"] spec.email = ["cncf-openfeature-contributors@lists.cncf.io"] spec.summary = "Meta provider for the OpenFeature Ruby SDK" spec.description = "The MetaProvider wraps multiple other providers and uses a given strategy to resolve flags using all of them." - spec.homepage = "https://github.com/open-feature/ruby-sdk-contrib/providers/openfeature-sdk-meta_provider" + spec.homepage = "https://github.com/open-feature/ruby-sdk-contrib/providers/openfeature-meta_provider" spec.license = "Apache-2.0" spec.required_ruby_version = ">= 3.1" spec.metadata["homepage_uri"] = spec.homepage - spec.metadata["source_code_uri"] = "https://github.com/open-feature/ruby-sdk-contrib/providers/openfeature-sdk-meta_provider" - spec.metadata["changelog_uri"] = "https://github.com/open-feature/ruby-sdk-contrib/blob/main/CHANGELOG.md" + spec.metadata["source_code_uri"] = "https://github.com/open-feature/ruby-sdk-contrib/providers/openfeature-meta_provider" + spec.metadata["changelog_uri"] = "https://github.com/open-feature/ruby-sdk-contrib/blob/main/providers/openfeature-meta_provider/CHANGELOG.md" spec.metadata["bug_tracker_uri"] = "https://github.com/open-feature/ruby-sdk-contrib/issues" spec.metadata["documentation_uri"] = "https://github.com/open-feature/ruby-sdk-contrib/README.md" diff --git a/providers/openfeature-sdk-meta_provider/spec/open_feature/sdk/provider/meta_provider_spec.rb b/providers/openfeature-meta_provider/spec/openfeature/meta_provider_spec.rb similarity index 98% rename from providers/openfeature-sdk-meta_provider/spec/open_feature/sdk/provider/meta_provider_spec.rb rename to providers/openfeature-meta_provider/spec/openfeature/meta_provider_spec.rb index e2ce587..12738d4 100644 --- a/providers/openfeature-sdk-meta_provider/spec/open_feature/sdk/provider/meta_provider_spec.rb +++ b/providers/openfeature-meta_provider/spec/openfeature/meta_provider_spec.rb @@ -48,7 +48,7 @@ end end -RSpec.describe OpenFeature::SDK::Provider::MetaProvider do +RSpec.describe OpenFeature::MetaProvider do subject(:meta_provider) { described_class.new(providers: [provider_one, provider_two]) } let(:provider_one) do diff --git a/providers/openfeature-sdk-meta_provider/spec/spec_helper.rb b/providers/openfeature-meta_provider/spec/spec_helper.rb similarity index 92% rename from providers/openfeature-sdk-meta_provider/spec/spec_helper.rb rename to providers/openfeature-meta_provider/spec/spec_helper.rb index 04ca114..77e0e83 100644 --- a/providers/openfeature-sdk-meta_provider/spec/spec_helper.rb +++ b/providers/openfeature-meta_provider/spec/spec_helper.rb @@ -2,7 +2,7 @@ require "bundler/setup" require "debug" -require "open_feature/sdk/provider/meta_provider" +require "openfeature/meta_provider" require "open_feature/sdk" RSpec.configure do |config| diff --git a/providers/openfeature-sdk-meta_provider/Gemfile b/providers/openfeature-sdk-meta_provider/Gemfile deleted file mode 100644 index 3a0cc27..0000000 --- a/providers/openfeature-sdk-meta_provider/Gemfile +++ /dev/null @@ -1,6 +0,0 @@ -# frozen_string_literal: true - -source "https://rubygems.org" - -# Specify your gem's dependencies in openfeature-sdk-meta_provider.gemspec -gemspec diff --git a/providers/openfeature-sdk-meta_provider/lib/open_feature/sdk/provider/meta_provider.rb b/providers/openfeature-sdk-meta_provider/lib/open_feature/sdk/provider/meta_provider.rb deleted file mode 100644 index e8fd9b4..0000000 --- a/providers/openfeature-sdk-meta_provider/lib/open_feature/sdk/provider/meta_provider.rb +++ /dev/null @@ -1,79 +0,0 @@ -# frozen_string_literal: true - -module OpenFeature - module SDK - module Provider - # Used to pull from multiple providers. - class MetaProvider - # @param providers [Array] - # @param strategy [Symbol] When `:first_match`, returns first matched resolution. Providers will be searched - # in the order they were given. Defaults to `:first_match`. - def initialize(providers:, strategy: :first_match) - @providers = providers - @strategy = strategy - end - - def metadata - ProviderMetadata.new(name: "MetaProvider: #{providers.map { |provider| provider.metadata.name }.join(", ")}") - end - - def init - providers.each { |provider| provider.init } - end - - def shutdown - providers.each(&:shutdown) - end - - def fetch_boolean_value(flag_key:, default_value:, evaluation_context: nil) - fetch_from_sources(default_value:) do |provider| - provider.fetch_boolean_value(flag_key:, default_value:, evaluation_context:) - end - end - - def fetch_number_value(flag_key:, default_value:, evaluation_context: nil) - fetch_from_sources(default_value:) do |provider| - provider.fetch_number_value(flag_key:, default_value:, evaluation_context:) - end - end - - def fetch_object_value(flag_key:, default_value:, evaluation_context: nil) - fetch_from_sources(default_value:) do |provider| - provider.fetch_object_value(flag_key:, default_value:, evaluation_context:) - end - end - - def fetch_string_value(flag_key:, default_value:, evaluation_context: nil) - fetch_from_sources(default_value:) do |provider| - provider.fetch_string_value(flag_key:, default_value:, evaluation_context:) - end - end - - private - - attr_reader :providers, :strategy - - def fetch_from_sources(default_value:, &blk) - case strategy - when :first_match - successful_details = providers.each do |provider| - details = yield(provider) - - break details if details.error_code.nil? - rescue - next - end - - if successful_details.is_a?(ResolutionDetails) - successful_details - else - ResolutionDetails.new(value: default_value, error_code: ErrorCode::GENERAL, reason: Reason::ERROR) - end - else - ResolutionDetails.new(value: default_value, error_code: ErrorCode::GENERAL, reason: "Unknown strategy for MetaProvider") - end - end - end - end - end -end diff --git a/release-please-config.json b/release-please-config.json new file mode 100644 index 0000000..1020ece --- /dev/null +++ b/release-please-config.json @@ -0,0 +1,80 @@ +{ + "separate-pull-requests": true, + "packages": { + "providers/openfeature-flagd-provider": { + "package-name": "openfeature-flagd-provider", + "version-file": "lib/openfeature/flagd/provider/version.rb", + "bump-minor-pre-major": true, + "bump-patch-for-minor-pre-major": true, + "versioning": "default", + "extra-files": [ + "README.md" + ] + }, + "providers/openfeature-meta_provider": { + "package-name": "openfeature-meta_provider", + "version-file": "lib/openfeature/meta_provider_version.rb", + "bump-minor-pre-major": true, + "bump-patch-for-minor-pre-major": true, + "versioning": "default", + "extra-files": [ + "README.md" + ] + } + }, + "changelog-sections": [ + { + "type": "fix", + "section": "๐Ÿ› Bug Fixes" + }, + { + "type": "feat", + "section": "โœจ New Features" + }, + { + "type": "chore", + "section": "๐Ÿงน Chore" + }, + { + "type": "docs", + "section": "๐Ÿ“š Documentation" + }, + { + "type": "perf", + "section": "๐Ÿš€ Performance" + }, + { + "type": "build", + "hidden": true, + "section": "๐Ÿ› ๏ธ Build" + }, + { + "type": "deps", + "section": "๐Ÿ“ฆ Dependencies" + }, + { + "type": "ci", + "hidden": true, + "section": "๐Ÿšฆ CI" + }, + { + "type": "refactor", + "section": "๐Ÿ”„ Refactoring" + }, + { + "type": "revert", + "section": "๐Ÿ”™ Reverts" + }, + { + "type": "style", + "hidden": true, + "section": "๐ŸŽจ Styling" + }, + { + "type": "test", + "hidden": true, + "section": "๐Ÿงช Tests" + } + ], + "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json" +} diff --git a/ruby-sdk-contrib.code-workspace b/ruby-sdk-contrib.code-workspace index 49f9af4..8a3f8ce 100644 --- a/ruby-sdk-contrib.code-workspace +++ b/ruby-sdk-contrib.code-workspace @@ -4,7 +4,7 @@ "path": "providers/openfeature-flagd-provider" }, { - "path": "providers/openfeature-sdk-meta_provider" + "path": "providers/openfeature-meta_provider" } ] }