diff --git a/.gitignore b/.gitignore index 91226854d..29cb72ad9 100644 --- a/.gitignore +++ b/.gitignore @@ -41,7 +41,6 @@ latest.dump /node_modules yarn-debug.log* .yarn-integrity -.env # Ignore storybook static site generation app/javascript/storybook-static/ diff --git a/.gitpod.yml b/.gitpod.yml index 6376f0fcb..7365367ba 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -21,7 +21,7 @@ tasks: redis-server & /home/gitpod/elasticsearch-7.5.2/bin/elasticsearch & init: > - cp config/.env_sample .env && + cp config/sample_application.yml config/application.yml && gem install solargraph && bin/setup command: > diff --git a/.travis.yml b/.travis.yml index 1caee957b..4324b254b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,6 +24,8 @@ env: # Dummy values needed to verify the app boots via "rails runner" - APP_PROTOCOL=http:// - APP_DOMAIN=localhost:3000 + - SENDGRID_USERNAME_ACCEL=dummy + - SENDGRID_PASSWORD_ACCEL=dummy - HEROKU_APP_URL=practicaldev.herokuapp.com - SECRET_KEY_BASE=dummydummydummy - GITHUB_KEY=dummy @@ -43,7 +45,6 @@ install: true script: - date --rfc-3339=seconds - nvm install - - cp config/.env_sample .env - pkill -9 -f elasticsearch || true - curl -s -O https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.5.2-amd64.deb - sudo dpkg -i --force-confnew elasticsearch-7.5.2-amd64.deb diff --git a/Envfile b/Envfile new file mode 100644 index 000000000..92bc254cd --- /dev/null +++ b/Envfile @@ -0,0 +1,177 @@ +# Most of the things are optional. If you need to use a +# custom key, please create an application.yml for it + +enable_defaults! { ENV["RACK_ENV"] != "production" } + +################################################ +############## Basic configuration ############# +################################################ + +# App domain + Protocol setting for development +variable :APP_DOMAIN, :String, default: "localhost:3000" +variable :APP_PROTOCOL, :String, default: "http://" + +# Community Related Variables +variable :COMMUNITY_COPYRIGHT_START_YEAR, :String, default: "2016" +variable :COMMUNITY_NAME, :String, default: "DEV(local)" + +# Email related variables +variable :DEFAULT_EMAIL, :String, default: "yo@dev.to" + +# Service timeout length +variable :RACK_TIMEOUT_WAIT_TIMEOUT, :Integer, default: 100_000 +variable :RACK_TIMEOUT_SERVICE_TIMEOUT, :Integer, default: 100_000 + +# Heroku release slug used to bust caches on deploys +variable :HEROKU_SLUG_COMMIT, :String, default: "Optional" + +# Redis caching storage +variable :REDIS_URL, :String, default: "redis://localhost:6379" + +# Redis sessions storage +variable :REDIS_SESSIONS_URL, :String, default: "redis://localhost:6379" +variable :SESSION_KEY, :String, default: "_Dev_Community_Session" +variable :SESSION_EXPIRY_SECONDS, :Integer, default: 1209600 # two weeks in seconds + +# Redis Sidekiq storage +variable :REDIS_SIDEKIQ_URL, :String, default: "redis://localhost:6379" + +# Elasticsearch +variable :ELASTICSEARCH_URL, :String, default: "http://localhost:9200" + +# SSL config +variable :FORCE_SSL_IN_RAILS, :String, default: "not applicable in dev" + +################################################ +############## 3rd Party Services ############## +################################################ + +# It's best if you have the following configured +# for more development experience + +# GitHub +# (https://developer.github.com/v3/guides/basics-of-authentication/) +variable :GITHUB_KEY, :String, default: "" +variable :GITHUB_SECRET, :String, default: "" + +# Twitter +# (https://developer.twitter.com/en/docs/basics/authentication/oauth-2-0/application-only) +variable :TWITTER_KEY, :String, default: "" +variable :TWITTER_SECRET, :String, default: "" + +################################################ +######### Optional 3rd Party Services ########## +################################################ + +# Honeybadger for error tracking +# (https://docs.honeybadger.io/lib/ruby/getting-started/introduction.html) +variable :HONEYBADGER_API_KEY, :String, default: "Optional" +variable :HONEYBADGER_JS_API_KEY, :String, default: "Optional" + +# AWS for images storages +variable :AWS_ID, :String, default: "Optional" +variable :AWS_SECRET, :String, default: "Optional" +variable :AWS_BUCKET_NAME, :String, default: "Optional" +variable :AWS_UPLOAD_REGION, :String, default: "" + +# AWS SDK +# (https://docs.aws.amazon.com/sdk-for-ruby/v3/developer-guide/setup-config.html) +variable :AWS_DEFAULT_REGION, :String, default: "us-east-1" +variable :AWS_SDK_KEY, :String, default: "Optional" +variable :AWS_SDK_SECRET, :String, default: "Optional" + +# AWS for video storage +variable :AWS_S3_INPUT_BUCKET, :String, default: "Optional" +variable :AWS_S3_VIDEO_ID, :String, default: "Optional" +variable :AWS_S3_VIDEO_KEY, :String, default: "Optional" + +# Buffer for sending to buffer +# (https://buffer.com/developers/api) +variable :BUFFER_ACCESS_TOKEN, :String, default: "Optional" +variable :BUFFER_FACEBOOK_ID, :String, default: "Optional" +variable :BUFFER_LINKEDIN_ID, :String, default: "Optional" +variable :BUFFER_PROFILE_ID, :Integer, default: 0 +variable :BUFFER_TWITTER_ID, :String, default: "Optional" +variable :BUFFER_LISTINGS_PROFILE, :String, default: "Optional" + +# Cloudinary for image resizing and cache?? +# (https://cloudinary.com/documentation/rails_integration) +variable :CLOUDINARY_API_KEY, :String, default: "Optional" +variable :CLOUDINARY_API_SECRET, :String, default: "Optional" +variable :CLOUDINARY_CLOUD_NAME, :String, default: "Optional" +variable :CLOUDINARY_SECURE, :String, default: "Optional" + +# HTML/CSS to Image for generating social preview images +# (https://docs.htmlcsstoimage.com/example-code/ruby) +variable :HCTI_API_USER_ID, :String, default: "Optional" +variable :HCTI_API_KEY, :String, default: "Optional" + +# Fastly for edge caching +# (https://docs.fastly.com/api/) +variable :FASTLY_API_KEY, :String, default: "" +variable :FASTLY_SERVICE_ID, :String, default: "" + +# Honeycomb for monitoring and observability +# (https://www.honeycomb.io/) +variable :HONEYCOMB_API_KEY, :String, default: "" + +# Google analytic +# (https://developers.google.com/analytics/devguides/reporting/core/v4) +variable :GA_TRACKING_ID, :String, default: "Optional" + +# Mailchimp for mails +# (https://mailchimp.com/developer/) +variable :MAILCHIMP_API_KEY, :String, default: "Optional-valid" + +# Pusher for DEV Connect/notfications +# (https://pusher.com/docs) +variable :PUSHER_APP_ID, :String, default: "Optional" +variable :PUSHER_CLUSTER, :String, default: "Optional" +variable :PUSHER_KEY, :String, default: "Optional" +variable :PUSHER_SECRET, :String, default: "Optional" +variable :PUSHER_BEAMS_ID, :String, default: "Optional" +variable :PUSHER_BEAMS_KEY, :String, default: "Optional" + +# Google recaptcha +# (https://developers.google.com/recaptcha/intro) +variable :RECAPTCHA_SECRET, :String, default: "Optional" +variable :RECAPTCHA_SITE, :String, default: "Optional" + +# Slack for customer alerts +# (https://api.slack.com/) +variable :SLACK_CHANNEL, :String, default: "" +variable :SLACK_DEPLOY_CHANNEL, :String, default: "" +variable :SLACK_WEBHOOK_URL, :String, default: "" + +# Stripe for payment system +# (https://stripe.com/docs/api) +variable :STRIPE_PUBLISHABLE_KEY, :String, default: "Optional" +variable :STRIPE_SECRET_KEY, :String, default: "Optional" + +# For video calling in DEV Connect +# (https://www.twilio.com/docs/video) +variable :TWILIO_ACCOUNT_SID, :String, default: "Optional" +variable :TWILIO_VIDEO_API_KEY, :String, default: "Optional" +variable :TWILIO_VIDEO_API_SECRET, :String, default: "Optional" + +# For Twitch live stream integration +# (https://dev.twitch.tv/docs) +variable :TWITCH_CLIENT_ID, :String, default: "Optional" +variable :TWITCH_CLIENT_SECRET, :String, default: "Optional" +variable :TWITCH_WEBHOOK_SECRET, :String, default: "Optional" + +# For calling the Stack Exchange API +# (https://api.stackexchange.com/docs) +variable :STACK_EXCHANGE_APP_KEY, :String, default: "" + +group :production do + variable :SECRET_KEY_BASE, :String + + # Sendgrid + # (https://sendgrid.com/docs/API_Reference/api_v3.html) + variable :SENDGRID_USERNAME_ACCEL, :String + variable :SENDGRID_PASSWORD_ACCEL, :String + + # Heroku + variable :HEROKU_APP_URL, :String # practicaldev.herokuapp.com +end diff --git a/Gemfile b/Gemfile index f96607e65..d13d6a840 100644 --- a/Gemfile +++ b/Gemfile @@ -36,6 +36,7 @@ gem "doorkeeper", "~> 5.4" # Oauth 2 provider gem "elasticsearch", "~> 7.8" # Powers DEVs core search functionality gem "email_validator", "~> 2.0" # Email validator for Rails and ActiveModel gem "emoji_regex", "~> 3.0" # A pair of Ruby regular expressions for matching Unicode Emoji symbols +gem "envied", "~> 0.9" # Ensure presence and type of your app's ENV-variables gem "faraday-http-cache", "~> 2.2" # Middleware to handle HTTP caching gem "fastly", "~> 2.5" # Client library for the Fastly acceleration system gem "feedjira", "~> 3.1" # A feed fetching and parsing library @@ -133,7 +134,6 @@ group :development, :test do gem "amazing_print", "~> 1.2" # Great Ruby debugging companion: pretty print Ruby objects to visualize their structure gem "bullet", "~> 6.1" # help to kill N+1 queries and unused eager loading gem "capybara", "~> 3.33" # Capybara is an integration testing tool for rack based web applications - gem "dotenv-rails", "~> 2.7.6" # For loading ENV variables locally gem "faker", "~> 2.13" # A library for generating fake data such as names, addresses, and phone numbers gem "knapsack_pro", "~> 2.1.1" # Help parallelize Ruby spec builds gem "pry-byebug", "~> 3.8" # Combine 'pry' with 'byebug'. Adds 'step', 'next', 'finish', 'continue' and 'break' commands to control execution diff --git a/Gemfile.lock b/Gemfile.lock index 3ea670838..b6a03439f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -252,10 +252,6 @@ GEM unf (>= 0.0.5, < 1.0.0) doorkeeper (5.4.0) railties (>= 5) - dotenv (2.7.6) - dotenv-rails (2.7.6) - dotenv (= 2.7.6) - railties (>= 3.2) elasticsearch (7.8.1) elasticsearch-api (= 7.8.1) elasticsearch-transport (= 7.8.1) @@ -271,6 +267,8 @@ GEM activemodel emoji_regex (3.0.0) enumerable-statistics (2.0.1) + envied (0.9.3) + thor (~> 0.15) environs (1.1.0) equalizer (0.0.11) erb_lint (0.0.35) @@ -880,10 +878,10 @@ DEPENDENCIES devise_invitable (~> 2.0.0) dogstatsd-ruby (~> 4.8) doorkeeper (~> 5.4) - dotenv-rails (~> 2.7.6) elasticsearch (~> 7.8) email_validator (~> 2.0) emoji_regex (~> 3.0) + envied (~> 0.9) erb_lint (~> 0.0.34) exifr (>= 1.3.6) factory_bot_rails (~> 6.1) diff --git a/app/views/admin/configs/show.html.erb b/app/views/admin/configs/show.html.erb index 8ccdd51d5..967e2fdec 100644 --- a/app/views/admin/configs/show.html.erb +++ b/app/views/admin/configs/show.html.erb @@ -884,11 +884,13 @@ - <% ENV.sort.each do |key, value| %> - - <%= key %> - <%= value %> - + <% ENVied.config.variables.each do |v| %> + <% if v.group.in?(ENVied.required_groups) %> + + <%= v.name %> + <%= ApplicationConfig[v.name] %> + + <% end %> <% end %> diff --git a/bin/setup b/bin/setup index a4286a6fb..384ca0121 100755 --- a/bin/setup +++ b/bin/setup @@ -25,10 +25,6 @@ chdir APP_ROOT do # Install JavaScript dependencies if using Yarn system("bin/yarn") - # TEMPORARY @sre will remove before Sept 1, 2020 - puts "\n== Create .env File from application.yml ==" - system!("bin/rails create_dot_env_file") - puts "\n== Copying sample files ==" unless File.exist?("config/database.yml") cp "config/database.yml.sample", "config/database.yml" diff --git a/config/.env_sample b/config/.env_sample deleted file mode 100644 index 3f100f258..000000000 --- a/config/.env_sample +++ /dev/null @@ -1,156 +0,0 @@ -# App domain + Protocol setting for development -export APP_DOMAIN="localhost:3000" -export APP_PROTOCOL="http://" - -# Community Related Variables -export COMMUNITY_COPYRIGHT_START_YEAR="2016" -export COMMUNITY_NAME="DEV(local)" - -# Email related variables -export DEFAULT_EMAIL="yo@dev.to" - -# Service timeout length -export RACK_TIMEOUT_WAIT_TIMEOUT=100_000 -export RACK_TIMEOUT_SERVICE_TIMEOUT=100_000 - -# Heroku release slug used to bust caches on deploys -export HEROKU_SLUG_COMMIT="Optional" - -# Redis caching storage -export REDIS_URL="redis://localhost:6379" - -# Redis sessions storage -export REDIS_SESSIONS_URL="redis://localhost:6379" -export SESSION_KEY="_Dev_Community_Session" -export SESSION_EXPIRY_SECONDS=1209600 # two weeks in seconds - -# Redis Sidekiq storage -export REDIS_SIDEKIQ_URL="redis://localhost:6379" - -# Elasticsearch -export ELASTICSEARCH_URL="http://localhost:9200" - -# SSL config -export FORCE_SSL_IN_RAILS="not applicable in dev" - -################################################ -############## 3rd Party Services ############## -################################################ - -# It's best if you have the following configured -# for more development experience - -# GitHub -# (https://developer.github.com/v3/guides/basics-of-authentication/) -export GITHUB_KEY="" -export GITHUB_SECRET="" - -# Twitter -# (https://developer.twitter.com/en/docs/basics/authentication/oauth-2-0/application-only) -export TWITTER_KEY="" -export TWITTER_SECRET="" - -################################################ -######### Optional 3rd Party Services ########## -################################################ - -# Honeybadger for error tracking -# (https://docs.honeybadger.io/lib/ruby/getting-started/introduction.html) -export HONEYBADGER_API_KEY="Optional" -export HONEYBADGER_JS_API_KEY="Optional" - -# AWS for images storages -export AWS_ID="Optional" -export AWS_SECRET="Optional" -export AWS_BUCKET_NAME="Optional" -export AWS_UPLOAD_REGION="" - -# AWS SDK -# (https://docs.aws.amazon.com/sdk-for-ruby/v3/developer-guide/setup-config.html) -export AWS_DEFAULT_REGION="us-east-1" -export AWS_SDK_KEY="Optional" -export AWS_SDK_SECRET="Optional" - -# AWS for video storage -export AWS_S3_INPUT_BUCKET="Optional" -export AWS_S3_VIDEO_ID="Optional" -export AWS_S3_VIDEO_KEY="Optional" - -# Buffer for sending to buffer -# (https://buffer.com/developers/api) -export BUFFER_ACCESS_TOKEN="Optional" -export BUFFER_FACEBOOK_ID="Optional" -export BUFFER_LINKEDIN_ID="Optional" -export BUFFER_PROFILE_ID=0 -export BUFFER_TWITTER_ID="Optional" -export BUFFER_LISTINGS_PROFILE="Optional" - -# Cloudinary for image resizing and cache?? -# (https://cloudinary.com/documentation/rails_integration) -export CLOUDINARY_API_KEY="Optional" -export CLOUDINARY_API_SECRET="Optional" -export CLOUDINARY_CLOUD_NAME="Optional" -export CLOUDINARY_SECURE="Optional" - -# HTML/CSS to Image for generating social preview images -# (https://docs.htmlcsstoimage.com/example-code/ruby) -export HCTI_API_USER_ID="Optional" -export HCTI_API_KEY="Optional" - -# Fastly for edge caching -# (https://docs.fastly.com/api/) -export FASTLY_API_KEY="" -export FASTLY_SERVICE_ID="" - -# Honeycomb for monitoring and observability -# (https://www.honeycomb.io/) -export HONEYCOMB_API_KEY="" - -# Google analytic -# (https://developers.google.com/analytics/devguides/reporting/core/v4) -export GA_TRACKING_ID="Optional" - -# Mailchimp for mails -# (https://mailchimp.com/developer/) -export MAILCHIMP_API_KEY="Optional-valid" - -# Pusher for DEV Connect/notfications -# (https://pusher.com/docs) -export PUSHER_APP_ID= -export PUSHER_CLUSTER= -export PUSHER_KEY= -export PUSHER_SECRET= -export PUSHER_BEAMS_ID= -export PUSHER_BEAMS_KEY= - -# Google recaptcha -# (https://developers.google.com/recaptcha/intro) -export RECAPTCHA_SECRET="Optional" -export RECAPTCHA_SITE="Optional" - -# Slack for customer alerts -# (https://api.slack.com/) -export SLACK_CHANNEL="" -export SLACK_DEPLOY_CHANNEL="" -export SLACK_WEBHOOK_URL="" - -# Stripe for payment system -# (https://stripe.com/docs/api) -export STRIPE_PUBLISHABLE_KEY="Optional" -export STRIPE_SECRET_KEY="Optional" - -# For video calling in DEV Connect -# (https://www.twilio.com/docs/video) -export TWILIO_ACCOUNT_SID="Optional" -export TWILIO_VIDEO_API_KEY="Optional" -export TWILIO_VIDEO_API_SECRET="Optional" - -# For Twitch live stream integration -# (https://dev.twitch.tv/docs) -export TWITCH_CLIENT_ID="Optional" -export TWITCH_CLIENT_SECRET="Optional" -export TWITCH_WEBHOOK_SECRET="Optional" - -# For calling the Stack Exchange API -# (https://api.stackexchange.com/docs) -export STACK_EXCHANGE_APP_KEY="" diff --git a/config/application.rb b/config/application.rb index 19bfdd8ae..6cfa51c4f 100644 --- a/config/application.rb +++ b/config/application.rb @@ -17,8 +17,6 @@ require "sprockets/railtie" # you've limited to :test, :development, or :production. Bundler.require(*Rails.groups) -Dotenv::Railtie.load if Rails.env.test? || Rails.env.development? - module PracticalDeveloper class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. diff --git a/config/environments/production.rb b/config/environments/production.rb index dacaf4b37..828346228 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -110,12 +110,11 @@ Rails.application.configure do # Do not dump schema after migrations. config.active_record.dump_schema_after_migration = false - config.app_domain = ENV["APP_DOMAIN"] || "localhost:3000" - protocol = ENV["APP_PROTOCOL"] || "http://" + config.app_domain = ENV["APP_DOMAIN"] config.action_mailer.delivery_method = :smtp config.action_mailer.perform_deliveries = true - config.action_mailer.default_url_options = { host: protocol + config.app_domain } + config.action_mailer.default_url_options = { host: ENV["APP_PROTOCOL"] + ENV["APP_DOMAIN"] } ActionMailer::Base.smtp_settings = { address: "smtp.sendgrid.net", port: "587", @@ -126,14 +125,14 @@ Rails.application.configure do enable_starttls_auto: true } - if ENV["HEROKU_APP_URL"] != config.app_domain + if ENV["HEROKU_APP_URL"] != ENV["APP_DOMAIN"] config.middleware.use Rack::HostRedirect, - ENV["HEROKU_APP_URL"] => config.app_domain + ENV["HEROKU_APP_URL"] => ENV["APP_DOMAIN"] end end # rubocop:enable Metrics/BlockLength Rails.application.routes.default_url_options = { host: Rails.application.config.app_domain, - protocol: (ENV["APP_PROTOCOL"] || "http://").delete_suffix("://") + protocol: ENV["APP_PROTOCOL"].delete_suffix("://") } diff --git a/config/initializers/0_application_config.rb b/config/initializers/0_application_config.rb index d7e5d698e..154af296f 100644 --- a/config/initializers/0_application_config.rb +++ b/config/initializers/0_application_config.rb @@ -1,19 +1,15 @@ +ENVied.require(*ENV["ENVIED_GROUPS"] || Rails.groups) + class ApplicationConfig URI_REGEXP = %r{(?https?://)?(?.+?)(?:\d+)?$}.freeze def self.[](key) - if ENV.key?(key) - ENV[key] - else - Rails.logger.warn("Unset ENV variable: #{key}.") - nil - end + ENVied.public_send(key) end def self.app_domain_no_port app_domain = self["APP_DOMAIN"] - return unless app_domain - - app_domain.match(URI_REGEXP)[:host] + match = app_domain.match(URI_REGEXP) + match[:host] end end diff --git a/config/initializers/aws_sdk.rb b/config/initializers/aws_sdk.rb index 05218d72f..4460eb360 100644 --- a/config/initializers/aws_sdk.rb +++ b/config/initializers/aws_sdk.rb @@ -1,5 +1,5 @@ Rails.application.reloader.to_prepare do - AWS_LAMBDA = if Rails.env.production? && ApplicationConfig["AWS_SDK_KEY"].present? + AWS_LAMBDA = if Rails.env.production? Aws::Lambda::Client.new( region: ApplicationConfig["AWS_DEFAULT_REGION"], access_key_id: ApplicationConfig["AWS_SDK_KEY"], diff --git a/config/initializers/carrierwave.rb b/config/initializers/carrierwave.rb index 132f71daa..ec320e910 100644 --- a/config/initializers/carrierwave.rb +++ b/config/initializers/carrierwave.rb @@ -27,7 +27,7 @@ CarrierWave.configure do |config| } config.asset_host = "https://#{ApplicationConfig['APP_DOMAIN']}/images" config.fog_public = false - elsif ApplicationConfig["AWS_ID"].present? + else region = ApplicationConfig["AWS_UPLOAD_REGION"].presence || ApplicationConfig["AWS_DEFAULT_REGION"] config.fog_credentials = { provider: "AWS", @@ -35,10 +35,6 @@ CarrierWave.configure do |config| aws_secret_access_key: ApplicationConfig["AWS_SECRET"], region: region } - else - # Fallback on file storage if AWS creds are not present - config.asset_host = "https://#{ApplicationConfig['APP_DOMAIN']}/images" - config.storage = :file end config.fog_directory = ApplicationConfig["AWS_BUCKET_NAME"] config.storage = :fog diff --git a/config/initializers/pusher.rb b/config/initializers/pusher.rb index 7b0dfbf9a..47a2e7858 100644 --- a/config/initializers/pusher.rb +++ b/config/initializers/pusher.rb @@ -1,15 +1,13 @@ require "pusher/push_notifications" -if ApplicationConfig["PUSHER_APP_ID"].present? - Pusher.app_id = ApplicationConfig["PUSHER_APP_ID"] - Pusher.key = ApplicationConfig["PUSHER_KEY"] - Pusher.secret = ApplicationConfig["PUSHER_SECRET"] - Pusher.cluster = ApplicationConfig["PUSHER_CLUSTER"] - Pusher.logger = Rails.logger - Pusher.encrypted = true +Pusher.app_id = ApplicationConfig["PUSHER_APP_ID"] +Pusher.key = ApplicationConfig["PUSHER_KEY"] +Pusher.secret = ApplicationConfig["PUSHER_SECRET"] +Pusher.cluster = ApplicationConfig["PUSHER_CLUSTER"] +Pusher.logger = Rails.logger +Pusher.encrypted = true - Pusher::PushNotifications.configure do |config| - config.instance_id = ApplicationConfig["PUSHER_BEAMS_ID"] - config.secret_key = ApplicationConfig["PUSHER_BEAMS_KEY"] - end +Pusher::PushNotifications.configure do |config| + config.instance_id = ApplicationConfig["PUSHER_BEAMS_ID"] + config.secret_key = ApplicationConfig["PUSHER_BEAMS_KEY"] end diff --git a/config/initializers/slack_notifier.rb b/config/initializers/slack_notifier.rb index be6a289f8..7bda893d0 100644 --- a/config/initializers/slack_notifier.rb +++ b/config/initializers/slack_notifier.rb @@ -4,6 +4,14 @@ class NoOpHTTPClient end end +def create_normal_notifier + Slack::Notifier.new( + ApplicationConfig["SLACK_WEBHOOK_URL"], + channel: ApplicationConfig["SLACK_CHANNEL"], + username: "activity_bot", + ) +end + def create_test_channel_notifier return create_stubbed_notifier if ApplicationConfig["SLACK_WEBHOOK_URL"].blank? @@ -33,7 +41,7 @@ def init_slack_client } end - webhook_url = ApplicationConfig["SLACK_WEBHOOK_URL"] || "" + webhook_url = ApplicationConfig["SLACK_WEBHOOK_URL"] use_no_op_client = Rails.env.test? || webhook_url.blank? Slack::Notifier.new(webhook_url) do diff --git a/config/sample_application.yml b/config/sample_application.yml index c94c2f6ce..32b00715e 100644 --- a/config/sample_application.yml +++ b/config/sample_application.yml @@ -1,156 +1,14 @@ -# App domain + Protocol setting for development -APP_DOMAIN: "localhost:3000" -APP_PROTOCOL: "http://" +GITHUB_KEY: +GITHUB_SECRET: -# Community Related Variables -COMMUNITY_COPYRIGHT_START_YEAR: "2016" -COMMUNITY_NAME: "DEV(local)" +TWITTER_KEY: +TWITTER_SECRET: -# Email related variables -DEFAULT_EMAIL: "yo@dev.to" +PUSHER_APP_ID: +PUSHER_KEY: +PUSHER_SECRET: +PUSHER_CLUSTER: -# Service timeout length -RACK_TIMEOUT_WAIT_TIMEOUT: 100_000 -RACK_TIMEOUT_SERVICE_TIMEOUT: 100_000 - -# Heroku release slug used to bust caches on deploys -HEROKU_SLUG_COMMIT: "Optional" - -# Redis caching storage -REDIS_URL: "redis://localhost:6379" - -# Redis sessions storage -REDIS_SESSIONS_URL: "redis://localhost:6379" -SESSION_KEY: "_Dev_Community_Session" -SESSION_EXPIRY_SECONDS: 1209600 # two weeks in seconds - -# Redis Sidekiq storage -REDIS_SIDEKIQ_URL: "redis://localhost:6379" - -# Elasticsearch -ELASTICSEARCH_URL: "http://localhost:9200" - -# SSL config -FORCE_SSL_IN_RAILS: "not applicable in dev" - -################################################ -############## 3rd Party Services ############## -################################################ - -# It's best if you have the following configured -# for more development experience - -# GitHub -# (https://developer.github.com/v3/guides/basics-of-authentication/) -GITHUB_KEY: "" -GITHUB_SECRET: "" - -# Twitter -# (https://developer.twitter.com/en/docs/basics/authentication/oauth-2-0/application-only) -TWITTER_KEY: "" -TWITTER_SECRET: "" - -################################################ -######### Optional 3rd Party Services ########## -################################################ - -# Honeybadger for error tracking -# (https://docs.honeybadger.io/lib/ruby/getting-started/introduction.html) -HONEYBADGER_API_KEY: "Optional" -HONEYBADGER_JS_API_KEY: "Optional" - -# AWS for images storages -AWS_ID: "Optional" -AWS_SECRET: "Optional" -AWS_BUCKET_NAME: "Optional" -AWS_UPLOAD_REGION: "" - -# AWS SDK -# (https://docs.aws.amazon.com/sdk-for-ruby/v3/developer-guide/setup-config.html) -AWS_DEFAULT_REGION: "us-east-1" -AWS_SDK_KEY: "Optional" -AWS_SDK_SECRET: "Optional" - -# AWS for video storage -AWS_S3_INPUT_BUCKET: "Optional" -AWS_S3_VIDEO_ID: "Optional" -AWS_S3_VIDEO_KEY: "Optional" - -# Buffer for sending to buffer -# (https://buffer.com/developers/api) -BUFFER_ACCESS_TOKEN: "Optional" -BUFFER_FACEBOOK_ID: "Optional" -BUFFER_LINKEDIN_ID: "Optional" -BUFFER_PROFILE_ID: 0 -BUFFER_TWITTER_ID: "Optional" -BUFFER_LISTINGS_PROFILE: "Optional" - -# Cloudinary for image resizing and cache?? -# (https://cloudinary.com/documentation/rails_integration) -CLOUDINARY_API_KEY: "Optional" -CLOUDINARY_API_SECRET: "Optional" -CLOUDINARY_CLOUD_NAME: "Optional" -CLOUDINARY_SECURE: "Optional" - -# HTML/CSS to Image for generating social preview images -# (https://docs.htmlcsstoimage.com/example-code/ruby) -HCTI_API_USER_ID: "Optional" -HCTI_API_KEY: "Optional" - -# Fastly for edge caching -# (https://docs.fastly.com/api/) -FASTLY_API_KEY: "" -FASTLY_SERVICE_ID: "" - -# Honeycomb for monitoring and observability -# (https://www.honeycomb.io/) -HONEYCOMB_API_KEY: "" - -# Google analytic -# (https://developers.google.com/analytics/devguides/reporting/core/v4) -GA_TRACKING_ID: "Optional" - -# Mailchimp for mails -# (https://mailchimp.com/developer/) -MAILCHIMP_API_KEY: "Optional-valid" - -# Pusher for DEV Connect/notfications -# (https://pusher.com/docs) -PUSHER_APP_ID: "Optional" -PUSHER_CLUSTER: "Optional" -PUSHER_KEY: "Optional" -PUSHER_SECRET: "Optional" -PUSHER_BEAMS_ID: "Optional" -PUSHER_BEAMS_KEY: "Optional" - -# Google recaptcha -# (https://developers.google.com/recaptcha/intro) -RECAPTCHA_SECRET: "Optional" -RECAPTCHA_SITE: "Optional" - -# Slack for customer alerts -# (https://api.slack.com/) -SLACK_CHANNEL: "" -SLACK_DEPLOY_CHANNEL: "" -SLACK_WEBHOOK_URL: "" - -# Stripe for payment system -# (https://stripe.com/docs/api) -STRIPE_PUBLISHABLE_KEY: "Optional" -STRIPE_SECRET_KEY: "Optional" - -# For video calling in DEV Connect -# (https://www.twilio.com/docs/video) -TWILIO_ACCOUNT_SID: "Optional" -TWILIO_VIDEO_API_KEY: "Optional" -TWILIO_VIDEO_API_SECRET: "Optional" - -# For Twitch live stream integration -# (https://dev.twitch.tv/docs) -TWITCH_CLIENT_ID: "Optional" -TWITCH_CLIENT_SECRET: "Optional" -TWITCH_WEBHOOK_SECRET: "Optional" - -# For calling the Stack Exchange API -# (https://api.stackexchange.com/docs) -STACK_EXCHANGE_APP_KEY: "" +TWITCH_CLIENT_ID: +TWITCH_CLIENT_SECRET: +TWITCH_WEBHOOK_SECRET: diff --git a/docs/backend/configuration.md b/docs/backend/configuration.md index 5f25d802b..4d15fcc42 100644 --- a/docs/backend/configuration.md +++ b/docs/backend/configuration.md @@ -6,20 +6,21 @@ title: Configuration We currently use the following gems for configuring the application: -- [dotenv](https://github.com/bkeepers/dotenv) +- [ENVied](https://github.com/eval/envied) - [rails-settings-cached](https://github.com/huacnlee/rails-settings-cached) - [vault](https://github.com/hashicorp/vault-ruby) -## dotenv +## ENVied -This gem is used for configuring environment variables for test and development -environments. Examples: +This gem is primarily used for configuring environment variables related to +credentials and third party services. Examples: - `REDIS_URL` - `FASTLY_API_KEY` - `STRIPE_SECRET_KEY` -Settings managed via your ENV can be found in +Settings managed via ENVied can be found in +[`Envfile`](https://github.com/forem/forem/blob/master/Envfile) (see [Configuring Environment Variables](../getting-started/config-env.md)) and viewed at `/admin/config` (see [the Admin guide](../admin/readme.md)): diff --git a/docs/faqs.md b/docs/faqs.md index f65c2e099..bb19ce99f 100644 --- a/docs/faqs.md +++ b/docs/faqs.md @@ -20,8 +20,8 @@ By default Rails logs to `log.development.log`. If, instead, you wish to log to `STDOUT` you can add the variable: -```shell -export RAILS_LOG_TO_STDOUT=true +```yaml +RAILS_LOG_TO_STDOUT: true ``` -to your own `.env` file. +to your own `config/application.yml` file. diff --git a/docs/getting-started/config-env.md b/docs/getting-started/config-env.md index d7e34ec6b..2a2027e14 100644 --- a/docs/getting-started/config-env.md +++ b/docs/getting-started/config-env.md @@ -10,27 +10,27 @@ provides a fake default for any missing keys. The [backend guide][backend_guide] will show you how to get free API keys for additional services that may be required to run certain parts of the app. -To set up keys for your local instance of Forem, you'll need to create an `.env` -file. You can do this by copying the file called `.env_sample` in the `config` -directory: +To set up keys for your local instance of Forem, you'll need to create an +`application.yml` file. You can do this by copying the file called +`sample_application.yml` in the `config` directory: ```shell -cp config/.env_sample .env +cp config/sample_application.yml config/application.yml ``` -Then, add each key you need to the `.env` file. For example, if you're setting -up GitHub authentication: +Then, add each key you need to the `application.yml` file. For example, if +you're setting up GitHub authentication: ```shell -export GITHUB_KEY="SOME_REAL_SECURE_KEY_HERE" -export GITHUB_SECRET="ANOTHER_REAL_SECURE_KEY_HERE" +GITHUB_KEY: "SOME_REAL_SECURE_KEY_HERE" +GITHUB_SECRET: "ANOTHER_REAL_SECURE_KEY_HERE" ``` -(Don't worry, your `.env` file is ignored by git) +(Don't worry, your `application.yml` file is ignored by git) -If you are missing `ENV` variables when you boot your application you will see a -warning message in your logs when you try to access that variable -`Unset ENV variable: xyz`. +If you are missing `ENV` variables on bootup, the [envied][envied] gem will +alert you with messages similar to +`'error_on_missing_variables!': The following environment variables should be set: A_MISSING_KEY.`. Only certain features require "real" keys, so you may be able to add them as you work on different areas of the application. diff --git a/docs/installation/containers.md b/docs/installation/containers.md index 5ca6283ff..36f8defd4 100644 --- a/docs/installation/containers.md +++ b/docs/installation/containers.md @@ -67,15 +67,16 @@ with Podman. You can install it by following these additional services that may be required to run certain parts of the app. - For any key that you wish to enter/replace: - 1. Create `.env` by copying from the provided template (i.e. with bash: - `cp config/.env_sample .env`). This is a personal file that is ignored - in git. + 1. Create `config/application.yml` by copying from the provided template + (i.e. with bash: + `cp config/sample_application.yml config/application.yml`). This is a + personal file that is ignored in git. 1. Obtain the development variable and apply the key you wish to enter/replace. i.e.: ```shell - export GITHUB_KEY="SOME_REAL_SECURE_KEY_HERE" - export GITHUB_SECRET="ANOTHER_REAL_SECURE_KEY_HERE" + GITHUB_KEY: "SOME_REAL_SECURE_KEY_HERE" + GITHUB_SECRET: "ANOTHER_REAL_SECURE_KEY_HERE" ``` - You do not need "real" keys for basic development. Some features require diff --git a/docs/installation/linux.md b/docs/installation/linux.md index 171e37466..357f0539e 100644 --- a/docs/installation/linux.md +++ b/docs/installation/linux.md @@ -97,15 +97,16 @@ NOTE: Make sure to download **the OSS version**, `elasticsearch-oss`. additional services that may be required to run certain parts of the app. - For any key that you wish to enter/replace: - 1. Create `.env` by copying from the provided template (i.e. with bash: - `cp config/.env_sample .env`). This is a personal file that is ignored - in git. + 1. Create `config/application.yml` by copying from the provided template + (i.e. with bash: + `cp config/sample_application.yml config/application.yml`). This is a + personal file that is ignored in git. 1. Obtain the development variable and apply the key you wish to enter/replace. i.e.: ```shell - export GITHUB_KEY="SOME_REAL_SECURE_KEY_HERE" - export GITHUB_SECRET="ANOTHER_REAL_SECURE_KEY_HERE" + GITHUB_KEY: "SOME_REAL_SECURE_KEY_HERE" + GITHUB_SECRET: "ANOTHER_REAL_SECURE_KEY_HERE" ``` - If you are missing `ENV` variables on bootup, the diff --git a/docs/installation/mac.md b/docs/installation/mac.md index b3442abeb..9d1abce07 100644 --- a/docs/installation/mac.md +++ b/docs/installation/mac.md @@ -217,15 +217,16 @@ your local Elasticsearch installation, for example: additional services that may be required to run certain parts of the app. - For any key that you wish to enter/replace, follow the steps below. - 1. Create `.env` by copying from the provided template (i.e. with bash: - `cp config/.env_sample .env`). This is a personal file that is ignored - in git. + 1. Create `config/application.yml` by copying from the provided template + (i.e. with bash: + `cp config/sample_application.yml config/application.yml`). This is a + personal file that is ignored in git. 2. Obtain the development variable and apply the key you wish to enter/replace. i.e.: ```shell - export GITHUB_KEY="SOME_REAL_SECURE_KEY_HERE" - export GITHUB_SECRET="ANOTHER_REAL_SECURE_KEY_HERE" + GITHUB_KEY: "SOME_REAL_SECURE_KEY_HERE" + GITHUB_SECRET: "ANOTHER_REAL_SECURE_KEY_HERE" ``` - If you are missing `ENV` variables on bootup, the diff --git a/docs/installation/postgresql.md b/docs/installation/postgresql.md index 2bd9ccce2..8a475107b 100644 --- a/docs/installation/postgresql.md +++ b/docs/installation/postgresql.md @@ -32,17 +32,17 @@ The go into depth on how Rails merges the existing `database.yml` with the connection string. -### Setup `DATABASE_URL` in .env +### Setup `DATABASE_URL` in application.yml -1. Open your `.env` +1. Open your `config/application.yml` 1. Add the following: -```shell -export DATABASE_URL=postgresql://USERNAME:PASSWORD@localhost +```yml +DATABASE_URL: postgresql://USERNAME:PASSWORD@localhost # Optional: If your test database is in a different url, be sure to set this. -export DATABASE_URL_TEST=postgresql://USERNAME:PASSWORD@localhost +DATABASE_URL_TEST: postgresql://USERNAME:PASSWORD@localhost ``` 1. Replace `USERNAME` with your database username, `PASSWORD` with your database diff --git a/docs/installation/vault.md b/docs/installation/vault.md index 7a565af3b..6e0f34e30 100644 --- a/docs/installation/vault.md +++ b/docs/installation/vault.md @@ -99,11 +99,11 @@ The final command will give you the following output: The `token` output from above is what you will use in your application to access Vault. All that is left to do is set the appropriate ENV variables in your -`.env` file. +`application.yml` file. -```shell -export VAULT_TOKEN=important-policy-token export VAULT_SECRET_NAMESPACE= +```yml +VAULT_TOKEN: important-policy-token +VAULT_SECRET_NAMESPACE: ``` Restart your application to start using Vault. One easy way to see it in action diff --git a/docs/installation/windows.md b/docs/installation/windows.md index d6c0b7b2f..5e6bb4749 100644 --- a/docs/installation/windows.md +++ b/docs/installation/windows.md @@ -254,15 +254,16 @@ To install Elasticsearch perform the following steps: additional services that may be required to run certain parts of the app. - For any key that you wish to enter/replace: - 1. Create `.env` by copying from the provided template (ie. with bash: - `cp config/.env_sample .env`). This is a personal file that is ignored - in git. + 1. Create `config/application.yml` by copying from the provided template + (ie. with bash: + `cp config/sample_application.yml config/application.yml`). This is a + personal file that is ignored in git. 1. Obtain the development variable and apply the key you wish to enter/replace. ie: ```shell - export GITHUB_KEY="SOME_REAL_SECURE_KEY_HERE" - export GITHUB_SECRET="ANOTHER_REAL_SECURE_KEY_HERE" + GITHUB_KEY: "SOME_REAL_SECURE_KEY_HERE" + GITHUB_SECRET: "ANOTHER_REAL_SECURE_KEY_HERE" ``` - If you are missing `ENV` variables on bootup, the @@ -328,7 +329,8 @@ There are currently two work-arounds. 1. `docker run -d --name selenium-hub -p 4444:4444 selenium/hub:3.141.59-20200409` 2. `CH=$(docker run --rm --name=ch --link selenium-hub:hub -v /dev/shm:/dev/shm selenium/node-chrome:3.141.59-20200409)` - 3. Add `export SELENIUM_URL="http://localhost:4444/wd/hub"` to your `.env` + 3. Add `SELENIUM_URL: "http://localhost:4444/wd/hub"` to your + `application.yml` 4. Run your System test! 2. Port forward with `socats` (more info needed). diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 60c1700cb..49c4829c3 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -96,8 +96,8 @@ refer to ## CORS If you are experiencing CORS issues locally or need to display more information -about the CORS headers, add the following variable to your `.env`: +about the CORS headers, add the following variable to your `application.yml`: -```shell -export DEBUG_CORS=true +```yml +DEBUG_CORS: true ``` diff --git a/lib/tasks/temporary/env_variables.rake b/lib/tasks/temporary/env_variables.rake deleted file mode 100644 index d14dfcc83..000000000 --- a/lib/tasks/temporary/env_variables.rake +++ /dev/null @@ -1,18 +0,0 @@ -# Create a .env file from your application.yml file -task create_dot_env_file: :environment do - exit unless File.file?("config/application.yml") - - File.open(".env", "w") do |env_file| - File.open("config/application.yml", 'r') do |file| - file.each_line do |line| - new_line = line.gsub(": ", "=") - unless new_line.blank? || new_line.starts_with?("#") - new_line.prepend("export ") - end - env_file.write(new_line) - end - end - end - - File.delete("config/application.yml") -end diff --git a/spec/initializers/application_config_spec.rb b/spec/initializers/application_config_spec.rb index 3c216b61c..6a7829d5f 100644 --- a/spec/initializers/application_config_spec.rb +++ b/spec/initializers/application_config_spec.rb @@ -1,12 +1,6 @@ require "rails_helper" describe ApplicationConfig do - it "logs warning if key is not found" do - allow(Rails.logger).to receive(:warn) - described_class["missing"] - expect(Rails.logger).to have_received(:warn).with("Unset ENV variable: missing.") - end - describe ".app_domain_no_port" do it "handles plain subdomain only name" do setup_app_domain("renner") diff --git a/vendor/cache/dotenv-2.7.6.gem b/vendor/cache/dotenv-2.7.6.gem deleted file mode 100644 index c3a414727..000000000 Binary files a/vendor/cache/dotenv-2.7.6.gem and /dev/null differ diff --git a/vendor/cache/dotenv-rails-2.7.6.gem b/vendor/cache/dotenv-rails-2.7.6.gem deleted file mode 100644 index 8f292af2b..000000000 Binary files a/vendor/cache/dotenv-rails-2.7.6.gem and /dev/null differ diff --git a/vendor/cache/envied-0.9.3.gem b/vendor/cache/envied-0.9.3.gem new file mode 100644 index 000000000..6e33088ae Binary files /dev/null and b/vendor/cache/envied-0.9.3.gem differ