diff --git a/.gitignore b/.gitignore
index 29cb72ad9..91226854d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -41,6 +41,7 @@ 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 7365367ba..6376f0fcb 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/sample_application.yml config/application.yml &&
+ cp config/.env_sample .env &&
gem install solargraph &&
bin/setup
command: >
diff --git a/.travis.yml b/.travis.yml
index 4324b254b..1caee957b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -24,8 +24,6 @@ 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
@@ -45,6 +43,7 @@ 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
deleted file mode 100644
index 92bc254cd..000000000
--- a/Envfile
+++ /dev/null
@@ -1,177 +0,0 @@
-# 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 8a821b878..0c98e2a64 100644
--- a/Gemfile
+++ b/Gemfile
@@ -36,7 +36,6 @@ 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
@@ -135,6 +134,7 @@ 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 7b70a90bf..3b2ecb9ec 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -252,6 +252,10 @@ 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)
@@ -267,8 +271,6 @@ 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 +882,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 967e2fdec..8ccdd51d5 100644
--- a/app/views/admin/configs/show.html.erb
+++ b/app/views/admin/configs/show.html.erb
@@ -884,13 +884,11 @@
- <% ENVied.config.variables.each do |v| %>
- <% if v.group.in?(ENVied.required_groups) %>
-
- | <%= v.name %> |
- <%= ApplicationConfig[v.name] %> |
-
- <% end %>
+ <% ENV.sort.each do |key, value| %>
+
+ | <%= key %> |
+ <%= value %> |
+
<% end %>
diff --git a/bin/setup b/bin/setup
index 384ca0121..a4286a6fb 100755
--- a/bin/setup
+++ b/bin/setup
@@ -25,6 +25,10 @@ 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
new file mode 100644
index 000000000..3f100f258
--- /dev/null
+++ b/config/.env_sample
@@ -0,0 +1,156 @@
+# 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 6cfa51c4f..19bfdd8ae 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -17,6 +17,8 @@ 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 828346228..dacaf4b37 100644
--- a/config/environments/production.rb
+++ b/config/environments/production.rb
@@ -110,11 +110,12 @@ Rails.application.configure do
# Do not dump schema after migrations.
config.active_record.dump_schema_after_migration = false
- config.app_domain = ENV["APP_DOMAIN"]
+ config.app_domain = ENV["APP_DOMAIN"] || "localhost:3000"
+ protocol = ENV["APP_PROTOCOL"] || "http://"
config.action_mailer.delivery_method = :smtp
config.action_mailer.perform_deliveries = true
- config.action_mailer.default_url_options = { host: ENV["APP_PROTOCOL"] + ENV["APP_DOMAIN"] }
+ config.action_mailer.default_url_options = { host: protocol + config.app_domain }
ActionMailer::Base.smtp_settings = {
address: "smtp.sendgrid.net",
port: "587",
@@ -125,14 +126,14 @@ Rails.application.configure do
enable_starttls_auto: true
}
- if ENV["HEROKU_APP_URL"] != ENV["APP_DOMAIN"]
+ if ENV["HEROKU_APP_URL"] != config.app_domain
config.middleware.use Rack::HostRedirect,
- ENV["HEROKU_APP_URL"] => ENV["APP_DOMAIN"]
+ ENV["HEROKU_APP_URL"] => config.app_domain
end
end
# rubocop:enable Metrics/BlockLength
Rails.application.routes.default_url_options = {
host: Rails.application.config.app_domain,
- protocol: ENV["APP_PROTOCOL"].delete_suffix("://")
+ protocol: (ENV["APP_PROTOCOL"] || "http://").delete_suffix("://")
}
diff --git a/config/initializers/0_application_config.rb b/config/initializers/0_application_config.rb
index 154af296f..d7e5d698e 100644
--- a/config/initializers/0_application_config.rb
+++ b/config/initializers/0_application_config.rb
@@ -1,15 +1,19 @@
-ENVied.require(*ENV["ENVIED_GROUPS"] || Rails.groups)
-
class ApplicationConfig
URI_REGEXP = %r{(?https?://)?(?.+?)(?:\d+)?$}.freeze
def self.[](key)
- ENVied.public_send(key)
+ if ENV.key?(key)
+ ENV[key]
+ else
+ Rails.logger.warn("Unset ENV variable: #{key}.")
+ nil
+ end
end
def self.app_domain_no_port
app_domain = self["APP_DOMAIN"]
- match = app_domain.match(URI_REGEXP)
- match[:host]
+ return unless app_domain
+
+ app_domain.match(URI_REGEXP)[:host]
end
end
diff --git a/config/initializers/aws_sdk.rb b/config/initializers/aws_sdk.rb
index 4460eb360..05218d72f 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?
+ AWS_LAMBDA = if Rails.env.production? && ApplicationConfig["AWS_SDK_KEY"].present?
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 ec320e910..132f71daa 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
- else
+ elsif ApplicationConfig["AWS_ID"].present?
region = ApplicationConfig["AWS_UPLOAD_REGION"].presence || ApplicationConfig["AWS_DEFAULT_REGION"]
config.fog_credentials = {
provider: "AWS",
@@ -35,6 +35,10 @@ 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 47a2e7858..7b0dfbf9a 100644
--- a/config/initializers/pusher.rb
+++ b/config/initializers/pusher.rb
@@ -1,13 +1,15 @@
require "pusher/push_notifications"
-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
+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::PushNotifications.configure do |config|
- config.instance_id = ApplicationConfig["PUSHER_BEAMS_ID"]
- config.secret_key = ApplicationConfig["PUSHER_BEAMS_KEY"]
+ Pusher::PushNotifications.configure do |config|
+ config.instance_id = ApplicationConfig["PUSHER_BEAMS_ID"]
+ config.secret_key = ApplicationConfig["PUSHER_BEAMS_KEY"]
+ end
end
diff --git a/config/initializers/slack_notifier.rb b/config/initializers/slack_notifier.rb
index 7bda893d0..be6a289f8 100644
--- a/config/initializers/slack_notifier.rb
+++ b/config/initializers/slack_notifier.rb
@@ -4,14 +4,6 @@ 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?
@@ -41,7 +33,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 32b00715e..c94c2f6ce 100644
--- a/config/sample_application.yml
+++ b/config/sample_application.yml
@@ -1,14 +1,156 @@
-GITHUB_KEY:
-GITHUB_SECRET:
+# App domain + Protocol setting for development
+APP_DOMAIN: "localhost:3000"
+APP_PROTOCOL: "http://"
-TWITTER_KEY:
-TWITTER_SECRET:
+# Community Related Variables
+COMMUNITY_COPYRIGHT_START_YEAR: "2016"
+COMMUNITY_NAME: "DEV(local)"
-PUSHER_APP_ID:
-PUSHER_KEY:
-PUSHER_SECRET:
-PUSHER_CLUSTER:
+# Email related variables
+DEFAULT_EMAIL: "yo@dev.to"
-TWITCH_CLIENT_ID:
-TWITCH_CLIENT_SECRET:
-TWITCH_WEBHOOK_SECRET:
+# 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: ""
diff --git a/docs/backend/configuration.md b/docs/backend/configuration.md
index 4d15fcc42..5f25d802b 100644
--- a/docs/backend/configuration.md
+++ b/docs/backend/configuration.md
@@ -6,21 +6,20 @@ title: Configuration
We currently use the following gems for configuring the application:
-- [ENVied](https://github.com/eval/envied)
+- [dotenv](https://github.com/bkeepers/dotenv)
- [rails-settings-cached](https://github.com/huacnlee/rails-settings-cached)
- [vault](https://github.com/hashicorp/vault-ruby)
-## ENVied
+## dotenv
-This gem is primarily used for configuring environment variables related to
-credentials and third party services. Examples:
+This gem is used for configuring environment variables for test and development
+environments. Examples:
- `REDIS_URL`
- `FASTLY_API_KEY`
- `STRIPE_SECRET_KEY`
-Settings managed via ENVied can be found in
-[`Envfile`](https://github.com/forem/forem/blob/master/Envfile) (see
+Settings managed via your ENV can be found in
[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 bb19ce99f..f65c2e099 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:
-```yaml
-RAILS_LOG_TO_STDOUT: true
+```shell
+export RAILS_LOG_TO_STDOUT=true
```
-to your own `config/application.yml` file.
+to your own `.env` file.
diff --git a/docs/getting-started/config-env.md b/docs/getting-started/config-env.md
index 2a2027e14..d7e34ec6b 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
-`application.yml` file. You can do this by copying the file called
-`sample_application.yml` in the `config` directory:
+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:
```shell
-cp config/sample_application.yml config/application.yml
+cp config/.env_sample .env
```
-Then, add each key you need to the `application.yml` file. For example, if
-you're setting up GitHub authentication:
+Then, add each key you need to the `.env` file. For example, if you're setting
+up GitHub authentication:
```shell
-GITHUB_KEY: "SOME_REAL_SECURE_KEY_HERE"
-GITHUB_SECRET: "ANOTHER_REAL_SECURE_KEY_HERE"
+export GITHUB_KEY="SOME_REAL_SECURE_KEY_HERE"
+export GITHUB_SECRET="ANOTHER_REAL_SECURE_KEY_HERE"
```
-(Don't worry, your `application.yml` file is ignored by git)
+(Don't worry, your `.env` file is ignored by git)
-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.`.
+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`.
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 36f8defd4..5ca6283ff 100644
--- a/docs/installation/containers.md
+++ b/docs/installation/containers.md
@@ -67,16 +67,15 @@ 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 `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. 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. Obtain the development variable and apply the key you wish to
enter/replace. i.e.:
```shell
- GITHUB_KEY: "SOME_REAL_SECURE_KEY_HERE"
- GITHUB_SECRET: "ANOTHER_REAL_SECURE_KEY_HERE"
+ export GITHUB_KEY="SOME_REAL_SECURE_KEY_HERE"
+ export 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 357f0539e..171e37466 100644
--- a/docs/installation/linux.md
+++ b/docs/installation/linux.md
@@ -97,16 +97,15 @@ 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 `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. 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. Obtain the development variable and apply the key you wish to
enter/replace. i.e.:
```shell
- GITHUB_KEY: "SOME_REAL_SECURE_KEY_HERE"
- GITHUB_SECRET: "ANOTHER_REAL_SECURE_KEY_HERE"
+ export GITHUB_KEY="SOME_REAL_SECURE_KEY_HERE"
+ export 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 9d1abce07..b3442abeb 100644
--- a/docs/installation/mac.md
+++ b/docs/installation/mac.md
@@ -217,16 +217,15 @@ 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 `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. 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.
2. Obtain the development variable and apply the key you wish to
enter/replace. i.e.:
```shell
- GITHUB_KEY: "SOME_REAL_SECURE_KEY_HERE"
- GITHUB_SECRET: "ANOTHER_REAL_SECURE_KEY_HERE"
+ export GITHUB_KEY="SOME_REAL_SECURE_KEY_HERE"
+ export 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 8a475107b..2bd9ccce2 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 application.yml
+### Setup `DATABASE_URL` in .env
-1. Open your `config/application.yml`
+1. Open your `.env`
1. Add the following:
-```yml
-DATABASE_URL: postgresql://USERNAME:PASSWORD@localhost
+```shell
+export DATABASE_URL=postgresql://USERNAME:PASSWORD@localhost
# Optional: If your test database is in a different url, be sure to set this.
-DATABASE_URL_TEST: postgresql://USERNAME:PASSWORD@localhost
+export 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 6e0f34e30..7a565af3b 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
-`application.yml` file.
+`.env` file.
-```yml
-VAULT_TOKEN: important-policy-token
-VAULT_SECRET_NAMESPACE:
+```shell
+export VAULT_TOKEN=important-policy-token export 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 5e6bb4749..d6c0b7b2f 100644
--- a/docs/installation/windows.md
+++ b/docs/installation/windows.md
@@ -254,16 +254,15 @@ 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 `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. 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. Obtain the development variable and apply the key you wish to
enter/replace. ie:
```shell
- GITHUB_KEY: "SOME_REAL_SECURE_KEY_HERE"
- GITHUB_SECRET: "ANOTHER_REAL_SECURE_KEY_HERE"
+ export GITHUB_KEY="SOME_REAL_SECURE_KEY_HERE"
+ export GITHUB_SECRET="ANOTHER_REAL_SECURE_KEY_HERE"
```
- If you are missing `ENV` variables on bootup, the
@@ -329,8 +328,7 @@ 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 `SELENIUM_URL: "http://localhost:4444/wd/hub"` to your
- `application.yml`
+ 3. Add `export SELENIUM_URL="http://localhost:4444/wd/hub"` to your `.env`
4. Run your System test!
2. Port forward with `socats` (more info needed).
diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md
index 49c4829c3..60c1700cb 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 `application.yml`:
+about the CORS headers, add the following variable to your `.env`:
-```yml
-DEBUG_CORS: true
+```shell
+export DEBUG_CORS=true
```
diff --git a/lib/tasks/temporary/env_variables.rake b/lib/tasks/temporary/env_variables.rake
new file mode 100644
index 000000000..003622788
--- /dev/null
+++ b/lib/tasks/temporary/env_variables.rake
@@ -0,0 +1,29 @@
+# Create a .env file from your application.yml file
+task create_dot_env_file: :environment do
+ exit if File.file?(".env")
+
+ # Used to set all defaults we have if not set already in application.yml
+ sample_app_yml = YAML.load_file("config/sample_application.yml")
+
+ # read existing lines
+ application_yml = File.open("config/application.yml", 'r').read
+
+
+ File.open(".env", "w") do |env_file|
+ # add default values only if they are not already present in the
+ # application.yml file which would result in a duplicate key
+ sample_app_yml.each_pair do |variable, value|
+ env_file.write("export #{variable}=#{value}\n") unless application_yml.include?(variable.to_s)
+ end
+
+ 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
+end
diff --git a/spec/initializers/application_config_spec.rb b/spec/initializers/application_config_spec.rb
index 6a7829d5f..3c216b61c 100644
--- a/spec/initializers/application_config_spec.rb
+++ b/spec/initializers/application_config_spec.rb
@@ -1,6 +1,12 @@
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
new file mode 100644
index 000000000..c3a414727
Binary files /dev/null and b/vendor/cache/dotenv-2.7.6.gem differ
diff --git a/vendor/cache/dotenv-rails-2.7.6.gem b/vendor/cache/dotenv-rails-2.7.6.gem
new file mode 100644
index 000000000..8f292af2b
Binary files /dev/null and b/vendor/cache/dotenv-rails-2.7.6.gem differ
diff --git a/vendor/cache/envied-0.9.3.gem b/vendor/cache/envied-0.9.3.gem
deleted file mode 100644
index 6e33088ae..000000000
Binary files a/vendor/cache/envied-0.9.3.gem and /dev/null differ