From 68124bb363ad7a1ac9d8fbdd338d8938ca091e0f Mon Sep 17 00:00:00 2001 From: Henne Vogelsang Date: Thu, 9 Nov 2023 19:08:33 +0100 Subject: [PATCH] Introduces dotenv-rails for setting environment variables --- .gitignore | 15 +++++++++------ Gemfile | 3 +++ Gemfile.lock | 5 +++++ config/database.yml | 15 ++++++++------- config/options.yml | 9 +++------ docker-compose.override.yml.example | 3 --- dotenv.example | 17 +++++++++++++++++ vendor/cache/dotenv-2.8.1.gem | Bin 0 -> 12800 bytes vendor/cache/dotenv-rails-2.8.1.gem | Bin 0 -> 10240 bytes 9 files changed, 45 insertions(+), 22 deletions(-) create mode 100644 dotenv.example create mode 100644 vendor/cache/dotenv-2.8.1.gem create mode 100644 vendor/cache/dotenv-rails-2.8.1.gem diff --git a/.gitignore b/.gitignore index 30a29907e..a7867ac19 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,15 @@ diff.diff # Bundler config /.bundle +# docker-compose override file +docker-compose.override.yml + +# dotenv files +.env +.env.production +.env.development +.env.test + # Static files in public public/111 public/112 @@ -37,9 +46,3 @@ public/package locale/*/software.edit.po locale/*/software.po.time_stamp -# Local databases -/db/*.sqlite3 -/db/*.db - -.byebug_history -docker-compose.override.yml diff --git a/Gemfile b/Gemfile index cc1e1b33b..b90e0883f 100644 --- a/Gemfile +++ b/Gemfile @@ -41,6 +41,9 @@ gem 'sentry-ruby' # for versioning gem 'paper_trail' +# for setting environment variables +gem 'dotenv-rails' + gem 'dalli' gem 'hashie' gem 'mini_magick' diff --git a/Gemfile.lock b/Gemfile.lock index c1ec2ed28..288da30ce 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -109,6 +109,10 @@ GEM delayed_job_active_record (4.1.8) activerecord (>= 3.0, < 8.0) delayed_job (>= 3.0, < 5) + dotenv (2.8.1) + dotenv-rails (2.8.1) + dotenv (= 2.8.1) + railties (>= 3.2) drb (2.1.1) ruby2_keywords erubi (1.12.0) @@ -376,6 +380,7 @@ DEPENDENCIES clockwork dalli delayed_job_active_record (~> 4.1) + dotenv-rails faker faraday faraday-decode_xml diff --git a/config/database.yml b/config/database.yml index e44f0dba6..4cf7ec5b5 100644 --- a/config/database.yml +++ b/config/database.yml @@ -1,4 +1,4 @@ -default: &default +defaults: &defaults adapter: postgresql encoding: utf8 pool: 5 @@ -10,15 +10,16 @@ default: &default database: <%= ENV.fetch('SOFTWARE_DB_NAME', 'postgres') %> development: - <<: *default + <<: *defaults database: software_development test: - <<: *default + <<: *defaults database: software_test production: - adapter: postgresql - encoding: utf8 - pool: 5 - timeout: 5000 + <<: *defaults + # no defaults for host/port as we might want to connect through a socket + host: <%= ENV.fetch('SOFTWARE_DB_HOST', nil) %> + port: <%= ENV.fetch('SOFTWARE_DB_PORT', nil) %> + database: software_production diff --git a/config/options.yml b/config/options.yml index be6214704..0eb704b5d 100644 --- a/config/options.yml +++ b/config/options.yml @@ -1,8 +1,8 @@ defaults: &defaults api_host: https://api.opensuse.org web_host: https://build.opensuse.org - api_username: <%= ENV['API_USERNAME'] %> - api_password: <%= ENV['API_PASSWORD'] %> + api_username: <%= ENV['SOFTWARE_OBS_API_USERNAME'] %> + api_password: <%= ENV['SOFTWARE_OBS_API_PASSWORD'] %> relative_url_root: development: <<: *defaults @@ -12,7 +12,4 @@ test: production: <<: *defaults relative_url_root: - api_username: <%= ENV['API_USERNAME'] %> - api_password: <%= ENV['API_PASSWORD'] %> - use_static: software.o.o - opensuse_cookie: <%= ENV['OPENSUSE_COOKIE'] %> + opensuse_cookie: <%= ENV['SOFTWARE_OPENSUSE_COOKIE'] %> diff --git a/docker-compose.override.yml.example b/docker-compose.override.yml.example index b1a884898..7942c2e27 100644 --- a/docker-compose.override.yml.example +++ b/docker-compose.override.yml.example @@ -4,6 +4,3 @@ services: build: args: CONTAINER_USERID: 1000 - environment: - - API_USERNAME=yourusername - - API_PASSWORD=password123 diff --git a/dotenv.example b/dotenv.example new file mode 100644 index 000000000..b9bf3be33 --- /dev/null +++ b/dotenv.example @@ -0,0 +1,17 @@ +# Rails Secret Key Base +# https://guides.rubyonrails.org/security.html#session-storage +# generate one with rails secret +SECRET_KEY_BASE=12345 + +# OBS API Secrets +# https://api.opensuse.org/apidocs/ +SOFTWARE_API_USERNAME=myusername +SOFTWARE_API_PASSWORD=mypassword +SOFTWARE_OPENSUSE_COOKIE=12345 + +# Postgres Database configuration +SOFTWARE_DB_USER=postgres +SOFTWARE_DB_PASSWORD=postgres +SOFTWARE_DB_NAME=postgres +SOFTWARE_DB_HOST=database +SOFTWARE_DB_PORT=5432 diff --git a/vendor/cache/dotenv-2.8.1.gem b/vendor/cache/dotenv-2.8.1.gem new file mode 100644 index 0000000000000000000000000000000000000000..1e95207174e7bdb334d550205d524d7e00c68d79 GIT binary patch literal 12800 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 XXSjdKRs6NdUkLn#z+VXbOA+`lyz