diff --git a/.circleci/config.yml b/.circleci/config.yml index 8201b95d..c6ff6938 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,6 +9,7 @@ workflows: - test-2.3 - test-2.4 - test-2.5 + - test-2.6 - test-jruby-9.2 ruby-docker-template: &ruby-docker-template @@ -57,6 +58,13 @@ jobs: - image: consul - image: redis - image: amazon/dynamodb-local + test-2.6: + <<: *ruby-docker-template + docker: + - image: circleci/ruby:2.6.2-stretch + - image: consul + - image: redis + - image: amazon/dynamodb-local test-jruby-9.2: <<: *ruby-docker-template docker: diff --git a/CHANGELOG.md b/CHANGELOG.md index af4ffb62..2a4c2269 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,12 +4,12 @@ All notable changes to the LaunchDarkly Ruby SDK will be documented in this file ## [5.5.5] - 2019-03-28 ### Fixed: -- Setting user attributes to non-string values when a string was expected would cause analytics events not to be processed. Also, in the case of the `secondary` attribute, this could cause evaluations to fail for a flag with a percentage rollout. The SDK will now convert attribute values to strings as needed. ([#131](https://github.com/launchdarkly/ruby-client/issues/131)) +- Setting user attributes to non-string values when a string was expected would cause analytics events not to be processed. Also, in the case of the `secondary` attribute, this could cause evaluations to fail for a flag with a percentage rollout. The SDK will now convert attribute values to strings as needed. ([#131](https://github.com/launchdarkly/ruby-server-sdk/issues/131)) ## [5.5.4] - 2019-03-29 ### Fixed: -- Fixed a missing `require` that could sometimes cause a `NameError` to be thrown when starting the client, depending on what other gems were installed. This bug was introduced in version 5.5.3. ([#129](https://github.com/launchdarkly/ruby-client/issues/129)) -- When an analytics event was generated for a feature flag because it is a prerequisite for another flag that was evaluated, the user data was being omitted from the event. ([#128](https://github.com/launchdarkly/ruby-client/issues/128)) +- Fixed a missing `require` that could sometimes cause a `NameError` to be thrown when starting the client, depending on what other gems were installed. This bug was introduced in version 5.5.3. ([#129](https://github.com/launchdarkly/ruby-server-sdk/issues/129)) +- When an analytics event was generated for a feature flag because it is a prerequisite for another flag that was evaluated, the user data was being omitted from the event. ([#128](https://github.com/launchdarkly/ruby-server-sdk/issues/128)) - If `track` or `identify` is called without a user, the SDK now logs a warning, and does not send an analytics event to LaunchDarkly (since it would not be processed without a user). - Added a link from the SDK readme to the guide regarding the client initialization. @@ -44,7 +44,7 @@ All notable changes to the LaunchDarkly Ruby SDK will be documented in this file ### Fixed: - Added or corrected a large number of documentation comments. All API classes and methods are now documented, and internal implementation details have been hidden from the documentation. You can view the latest documentation on [RubyDoc](https://www.rubydoc.info/gems/ldclient-rb). - Fixed a problem in the Redis feature store that would only happen under unlikely circumstances: trying to evaluate a flag when the LaunchDarkly client had not yet been fully initialized and the store did not yet have data in it, and then trying again when the client was still not ready but the store _did_ have data (presumably put there by another process). Previously, the second attempt would fail. -- In polling mode, the SDK did not correctly handle non-ASCII Unicode characters in feature flag data. ([#90](https://github.com/launchdarkly/ruby-client/issues/90)) +- In polling mode, the SDK did not correctly handle non-ASCII Unicode characters in feature flag data. ([#90](https://github.com/launchdarkly/ruby-server-sdk/issues/90)) ### Deprecated: - `RedisFeatureStore.new`. This implementation class may be changed or moved in the future; use `LaunchDarkly::Integrations::Redis::new_feature_store`. @@ -52,16 +52,16 @@ All notable changes to the LaunchDarkly Ruby SDK will be documented in this file ## [5.4.3] - 2019-01-11 ### Changed: -- The SDK is now compatible with `net-http-persistent` 3.x. (Thanks, [CodingAnarchy](https://github.com/launchdarkly/ruby-client/pull/113)!) +- The SDK is now compatible with `net-http-persistent` 3.x. (Thanks, [CodingAnarchy](https://github.com/launchdarkly/ruby-server-sdk/pull/113)!) ## [5.4.2] - 2019-01-04 ### Fixed: -- Fixed overly specific dependency versions of `concurrent-ruby` and `semantic`. ([#115](https://github.com/launchdarkly/ruby-client/issues/115)) +- Fixed overly specific dependency versions of `concurrent-ruby` and `semantic`. ([#115](https://github.com/launchdarkly/ruby-server-sdk/issues/115)) - Removed obsolete dependencies on `hashdiff` and `thread_safe`. ## [5.4.1] - 2018-11-05 ### Fixed: -- Fixed a `LoadError` in `file_data_source.rb`, which was added in 5.4.0. (Thanks, [kbarrette](https://github.com/launchdarkly/ruby-client/pull/110)!) +- Fixed a `LoadError` in `file_data_source.rb`, which was added in 5.4.0. (Thanks, [kbarrette](https://github.com/launchdarkly/ruby-server-sdk/pull/110)!) ## [5.4.0] - 2018-11-02 @@ -128,7 +128,7 @@ Fixed a regression in version 5.0.0 that could prevent the client from reconnect ## [3.0.2] - 2018-03-06 ## Fixed -- Improved efficiency of logging by not constructing messages that won't be visible at the current log level. (Thanks, [julik](https://github.com/launchdarkly/ruby-client/pull/98)!) +- Improved efficiency of logging by not constructing messages that won't be visible at the current log level. (Thanks, [julik](https://github.com/launchdarkly/ruby-server-sdk/pull/98)!) ## [3.0.1] - 2018-02-26 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c6b8dd20..ac126eec 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,37 @@ -Contributing to LaunchDarkly SDK for Ruby -========================================= +Contributing to the LaunchDarkly Server-side SDK for Ruby +================================================ -We encourage pull-requests and other contributions from the community. We've also published an [SDK contributor's guide](http://docs.launchdarkly.com/docs/sdk-contributors-guide) that provides a detailed explanation of how our SDKs work. +LaunchDarkly has published an [SDK contributor's guide](https://docs.launchdarkly.com/docs/sdk-contributors-guide) that provides a detailed explanation of how our SDKs work. See below for additional information on how to contribute to this SDK. + +Submitting bug reports and feature requests +------------------ + +The LaunchDarkly SDK team monitors the [issue tracker](https://github.com/launchdarkly/ruby-server-sdk/issues) in the SDK repository. Bug reports and feature requests specific to this SDK should be filed in this issue tracker. The SDK team will respond to all newly filed issues within two business days. + +Submitting pull requests +------------------ + +We encourage pull requests and other contributions from the community. Before submitting pull requests, ensure that all temporary or unintended code is removed. Don't worry about adding reviewers to the pull request; the LaunchDarkly SDK team will add themselves. The SDK team will acknowledge all pull requests within two business days. + +Build instructions +------------------ + +### Prerequisites + +This SDK is built with [Bundler](https://bundler.io/). To install Bundler, run `gem install bundler -v 1.17.3`. You might need `sudo` to execute the command successfully. As of this writing, the SDK does not support being built with Bundler 2.0. + +To install the runtime dependencies: + +``` +bundle install +``` + +### Testing + +To run all unit tests: + +``` +bundle exec rspec spec +``` + +By default, the full unit test suite includes live tests of the integrations for Consul, DynamoDB, and Redis. Those tests expect you to have instances of all of those databases running locally. To skip them, set the environment variable `LD_SKIP_DATABASE_TESTS=1` before running the tests. diff --git a/Gemfile.lock b/Gemfile.lock index 21a65cc1..aa131e55 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - ldclient-rb (5.5.2) + ldclient-rb (5.5.5) concurrent-ruby (~> 1.0) json (>= 1.8, < 3) ld-eventsource (~> 1.0) @@ -23,7 +23,7 @@ GEM aws-sigv4 (1.0.3) codeclimate-test-reporter (0.6.0) simplecov (>= 0.7.1, < 1.0.0) - concurrent-ruby (1.1.4) + concurrent-ruby (1.1.5) connection_pool (2.2.1) diff-lcs (1.3) diplomat (2.0.2) diff --git a/README.md b/README.md index 1c3eaa8a..7795ddb9 100644 --- a/README.md +++ b/README.md @@ -1,135 +1,26 @@ -LaunchDarkly SDK for Ruby +LaunchDarkly Server-side SDK for Ruby =========================== [![Gem Version](https://badge.fury.io/rb/ldclient-rb.svg)](http://badge.fury.io/rb/ldclient-rb) -[![Circle CI](https://circleci.com/gh/launchdarkly/ruby-client/tree/master.svg?style=svg)](https://circleci.com/gh/launchdarkly/ruby-client/tree/master) -[![Test Coverage](https://codeclimate.com/github/launchdarkly/ruby-client/badges/coverage.svg)](https://codeclimate.com/github/launchdarkly/ruby-client/coverage) -[![security](https://hakiri.io/github/launchdarkly/ruby-client/master.svg)](https://hakiri.io/github/launchdarkly/ruby-client/master) +[![Circle CI](https://circleci.com/gh/launchdarkly/ruby-server-sdk/tree/master.svg?style=svg)](https://circleci.com/gh/launchdarkly/ruby-server-sdk/tree/master) +[![Security](https://hakiri.io/github/launchdarkly/ruby-server-sdk/master.svg)](https://hakiri.io/github/launchdarkly/ruby-server-sdk/master) + +LaunchDarkly overview +------------------------- +[LaunchDarkly](https://www.launchdarkly.com) is a feature management platform that serves over 100 billion feature flags daily to help teams build better software, faster. [Get started](https://docs.launchdarkly.com/docs/getting-started) using LaunchDarkly today! + +[![Twitter Follow](https://img.shields.io/twitter/follow/launchdarkly.svg?style=social&label=Follow&maxAge=2592000)](https://twitter.com/intent/follow?screen_name=launchdarkly) Supported Ruby versions ----------------------- This version of the LaunchDarkly SDK has a minimum Ruby version of 2.2.6, or 9.1.6 for JRuby. -Quick setup +Getting started ----------- -1. Install the Ruby SDK with `gem` - -```shell -gem install ldclient-rb -``` - -2. Require the LaunchDarkly client: - -```ruby -require 'ldclient-rb' -``` - -3. Create a new LDClient with your SDK key: - -```ruby -client = LaunchDarkly::LDClient.new("your_sdk_key") -``` - -*NOTE: Please refer to [our documentation](https://docs.launchdarkly.com/docs/ruby-sdk-reference#section-initializing-ldclient-using-spring-unicorn-or-puma) for additional instructions on how to use LaunchDarkly with [Spring](https://github.com/rails/spring), [Unicorn](https://bogomips.org/unicorn/), or [Puma](https://github.com/puma/puma).* - -### Ruby on Rails - -1. Add `gem 'ldclient-rb'` to your Gemfile and `bundle install` - -2. Initialize the launchdarkly client in `config/initializers/launchdarkly.rb`: - -```ruby -Rails.configuration.ld_client = LaunchDarkly::LDClient.new("your_sdk_key") -``` - -3. You may want to include a function in your ApplicationController - -```ruby -def launchdarkly_settings - if current_user.present? - { - key: current_user.id, - anonymous: false, - email: current_user.email, - custom: { groups: current_user.groups.pluck(:name) }, - # Any other fields you may have - # e.g. lastName: current_user.last_name, - } - else - if Rails::VERSION::MAJOR <= 3 - hash_key = request.session_options[:id] - else - hash_key = session.id - end - # session ids should be private to prevent session hijacking - hash_key = Digest::SHA256.base64digest hash_key - { - key: hash_key, - anonymous: true, - } - end -end -``` - -4. In your controllers, access the client using - -```ruby -Rails.application.config.ld_client.variation('your.flag.key', launchdarkly_settings, false) -``` - -Note that this gem will automatically switch to using the Rails logger it is detected. - - -Your first feature flag ------------------------ - -1. Create a new feature flag on your [dashboard](https://app.launchdarkly.com). -2. In your application code, use the feature's key to check whether the flag is on for each user: - -```ruby -if client.variation("your.flag.key", {key: "user@test.com"}, false) - # application code to show the feature -else - # the code to run if the feature is off -end -``` - -HTTPS proxy ------------ - -The Ruby SDK uses Faraday and Socketry to handle its network traffic. Both of these provide built-in support for the use of an HTTPS proxy. If the HTTPS_PROXY environment variable is present then the SDK will proxy all network requests through the URL provided. (HTTP_PROXY is not used because all LaunchDarkly services require HTTPS.) - -How to set the HTTPS_PROXY environment variable on Mac/Linux systems: -``` -export HTTPS_PROXY=https://web-proxy.domain.com:8080 -``` - -How to set the HTTPS_PROXY environment variable on Windows systems: -``` -set HTTPS_PROXY=https://web-proxy.domain.com:8080 -``` - -If your proxy requires authentication then you can prefix the URN with your login information: -``` -export HTTPS_PROXY=http://user:pass@web-proxy.domain.com:8080 -``` -or -``` -set HTTPS_PROXY=http://user:pass@web-proxy.domain.com:8080 -``` - -Database integrations ---------------------- - -Feature flag data can be kept in a persistent store using Redis, DynamoDB, or Consul. These adapters are implemented in the `LaunchDarkly::Integrations::Redis`, `LaunchDarkly::Integrations::DynamoDB`, and `LaunchDarkly::Integrations::Consul` modules; to use them, call the `new_feature_store` method in the module, and put the returned object in the `feature_store` property of your client configuration. See the [API documentation](https://www.rubydoc.info/gems/ldclient-rb/LaunchDarkly/Integrations) and the [SDK reference guide](https://docs.launchdarkly.com/v2.0/docs/using-a-persistent-feature-store) for more information. - -Using flag data from a file ---------------------------- - -For testing purposes, the SDK can be made to read feature flag state from a file or files instead of connecting to LaunchDarkly. See `LaunchDarkly::FileDataSource` or the [SDK reference guide](https://docs.launchdarkly.com/v2.0/docs/reading-flags-from-a-file) for more details. +Refer to the [SDK documentation](https://docs.launchdarkly.com/docs/ruby-sdk-reference#section-getting-started) for instructions on getting started with using the SDK. Learn more ----------- @@ -140,37 +31,26 @@ Generated API documentation is on [RubyDoc.info](https://www.rubydoc.info/gems/l Testing ------- - + We run integration tests for all our SDKs using a centralized test harness. This approach gives us the ability to test for consistency across SDKs, as well as test networking behavior in a long-running application. These tests cover each method in the SDK, and verify that event sending, flag evaluation, stream reconnection, and other aspects of the SDK all behave correctly. - + Contributing ------------ - -See [Contributing](https://github.com/launchdarkly/ruby-client/blob/master/CONTRIBUTING.md). - + +We encourage pull requests and other contributions from the community. Check out our [contributing guidelines](CONTRIBUTING.md) for instructions on how to contribute to this SDK. + About LaunchDarkly ------------------- - +----------- + * LaunchDarkly is a continuous delivery platform that provides feature flags as a service and allows developers to iterate quickly and safely. We allow you to easily flag your features and manage them from the LaunchDarkly dashboard. With LaunchDarkly, you can: * Roll out a new feature to a subset of your users (like a group of users who opt-in to a beta tester group), gathering feedback and bug reports from real-world use cases. * Gradually roll out a feature to an increasing percentage of users, and track the effect that the feature has on key metrics (for instance, how likely is a user to complete a purchase if they have feature A versus feature B?). * Turn off a feature that you realize is causing performance problems in production, without needing to re-deploy, or even restart the application with a changed configuration file. * Grant access to certain features based on user attributes, like payment plan (eg: users on the ‘gold’ plan get access to more features than users in the ‘silver’ plan). Disable parts of your application to facilitate maintenance, without taking everything offline. -* LaunchDarkly provides feature flag SDKs for - * [Java](http://docs.launchdarkly.com/docs/java-sdk-reference "Java SDK") - * [JavaScript](http://docs.launchdarkly.com/docs/js-sdk-reference "LaunchDarkly JavaScript SDK") - * [PHP](http://docs.launchdarkly.com/docs/php-sdk-reference "LaunchDarkly PHP SDK") - * [Python](http://docs.launchdarkly.com/docs/python-sdk-reference "LaunchDarkly Python SDK") - * [Go](http://docs.launchdarkly.com/docs/go-sdk-reference "LaunchDarkly Go SDK") - * [Node.JS](http://docs.launchdarkly.com/docs/node-sdk-reference "LaunchDarkly Node SDK") - * [Electron](http://docs.launchdarkly.com/docs/electron-sdk-reference "LaunchDarkly Electron SDK") - * [.NET](http://docs.launchdarkly.com/docs/dotnet-sdk-reference "LaunchDarkly .Net SDK") - * [Ruby](http://docs.launchdarkly.com/docs/ruby-sdk-reference "LaunchDarkly Ruby SDK") - * [iOS](http://docs.launchdarkly.com/docs/ios-sdk-reference "LaunchDarkly iOS SDK") - * [Android](http://docs.launchdarkly.com/docs/android-sdk-reference "LaunchDarkly Android SDK") +* LaunchDarkly provides feature flag SDKs for a wide variety of languages and technologies. Check out [our documentation](https://docs.launchdarkly.com/docs) for a complete list. * Explore LaunchDarkly - * [launchdarkly.com](http://www.launchdarkly.com/ "LaunchDarkly Main Website") for more information - * [docs.launchdarkly.com](http://docs.launchdarkly.com/ "LaunchDarkly Documentation") for our documentation and SDKs - * [apidocs.launchdarkly.com](http://apidocs.launchdarkly.com/ "LaunchDarkly API Documentation") for our API documentation - * [blog.launchdarkly.com](http://blog.launchdarkly.com/ "LaunchDarkly Blog Documentation") for the latest product updates - * [Feature Flagging Guide](https://github.com/launchdarkly/featureflags/ "Feature Flagging Guide") for best practices and strategies + * [launchdarkly.com](https://www.launchdarkly.com/ "LaunchDarkly Main Website") for more information + * [docs.launchdarkly.com](https://docs.launchdarkly.com/ "LaunchDarkly Documentation") for our documentation and SDK reference guides + * [apidocs.launchdarkly.com](https://apidocs.launchdarkly.com/ "LaunchDarkly API Documentation") for our API documentation + * [blog.launchdarkly.com](https://blog.launchdarkly.com/ "LaunchDarkly Blog Documentation") for the latest product updates + * [Feature Flagging Guide](https://github.com/launchdarkly/featureflags/ "Feature Flagging Guide") for best practices and strategies \ No newline at end of file diff --git a/ldclient-rb.gemspec b/ldclient-rb.gemspec index 9fb4daa0..d1a19483 100644 --- a/ldclient-rb.gemspec +++ b/ldclient-rb.gemspec @@ -12,7 +12,7 @@ Gem::Specification.new do |spec| spec.email = ["team@launchdarkly.com"] spec.summary = "LaunchDarkly SDK for Ruby" spec.description = "Official LaunchDarkly SDK for Ruby" - spec.homepage = "https://github.com/launchdarkly/ruby-client" + spec.homepage = "https://github.com/launchdarkly/ruby-server-sdk" spec.license = "Apache-2.0" spec.files = `git ls-files -z`.split("\x0") diff --git a/scripts/release.sh b/scripts/release.sh index 18537846..314fe8b9 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -9,7 +9,7 @@ # When done you should commit and push the changes made. set -uxe -echo "Starting ruby-client release." +echo "Starting ruby-server-sdk release." VERSION=$1 @@ -24,4 +24,4 @@ gem build ldclient-rb.gemspec # Publish Ruby Gem gem push ldclient-rb-${VERSION}.gem -echo "Done with ruby-client release" \ No newline at end of file +echo "Done with ruby-server-sdk release" \ No newline at end of file diff --git a/spec/integrations/consul_feature_store_spec.rb b/spec/integrations/consul_feature_store_spec.rb index 13767686..45f87097 100644 --- a/spec/integrations/consul_feature_store_spec.rb +++ b/spec/integrations/consul_feature_store_spec.rb @@ -28,6 +28,7 @@ def clear_all_data describe "Consul feature store" do + return if ENV['LD_SKIP_DATABASE_TESTS'] == '1' # These tests will all fail if there isn't a local Consul instance running. diff --git a/spec/integrations/dynamodb_feature_store_spec.rb b/spec/integrations/dynamodb_feature_store_spec.rb index 4add3d53..d924b30a 100644 --- a/spec/integrations/dynamodb_feature_store_spec.rb +++ b/spec/integrations/dynamodb_feature_store_spec.rb @@ -89,7 +89,8 @@ def create_test_client describe "DynamoDB feature store" do - + return if ENV['LD_SKIP_DATABASE_TESTS'] == '1' + # These tests will all fail if there isn't a local DynamoDB instance running. create_table_if_necessary diff --git a/spec/redis_feature_store_spec.rb b/spec/redis_feature_store_spec.rb index 3da25f4f..0f372184 100644 --- a/spec/redis_feature_store_spec.rb +++ b/spec/redis_feature_store_spec.rb @@ -31,6 +31,8 @@ def clear_all_data describe LaunchDarkly::RedisFeatureStore do subject { LaunchDarkly::RedisFeatureStore } + return if ENV['LD_SKIP_DATABASE_TESTS'] == '1' + # These tests will all fail if there isn't a Redis instance running on the default port. context "real Redis with local cache" do