From e2e461ba0b9875ec16baeda38b836c492b469f0c Mon Sep 17 00:00:00 2001 From: Robert Starsi Date: Fri, 10 Oct 2025 10:13:03 +0200 Subject: [PATCH 01/24] fixtures for config targets --- test/fixtures/configs/deploy.yml | 2 -- test/fixtures/configs/dignity/deploy.yml | 0 test/fixtures/configs/kindness/deploy.production.yml | 0 test/fixtures/configs/nirvana/deploy.staging.yml | 0 test/fixtures/configs/nirvana/deploy.yml | 3 +++ 5 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 test/fixtures/configs/dignity/deploy.yml create mode 100644 test/fixtures/configs/kindness/deploy.production.yml create mode 100644 test/fixtures/configs/nirvana/deploy.staging.yml create mode 100644 test/fixtures/configs/nirvana/deploy.yml diff --git a/test/fixtures/configs/deploy.yml b/test/fixtures/configs/deploy.yml index 7ee3535..c43214b 100644 --- a/test/fixtures/configs/deploy.yml +++ b/test/fixtures/configs/deploy.yml @@ -1,5 +1,3 @@ -project: https://envirobly.com/projects/1 - services: app: public: true diff --git a/test/fixtures/configs/dignity/deploy.yml b/test/fixtures/configs/dignity/deploy.yml new file mode 100644 index 0000000..e69de29 diff --git a/test/fixtures/configs/kindness/deploy.production.yml b/test/fixtures/configs/kindness/deploy.production.yml new file mode 100644 index 0000000..e69de29 diff --git a/test/fixtures/configs/nirvana/deploy.staging.yml b/test/fixtures/configs/nirvana/deploy.staging.yml new file mode 100644 index 0000000..e69de29 diff --git a/test/fixtures/configs/nirvana/deploy.yml b/test/fixtures/configs/nirvana/deploy.yml new file mode 100644 index 0000000..56605ba --- /dev/null +++ b/test/fixtures/configs/nirvana/deploy.yml @@ -0,0 +1,3 @@ +services: + app: + public: false From f42a266efe150e575cf871fb9a3a9fb40e22dc30 Mon Sep 17 00:00:00 2001 From: Robert Starsi Date: Fri, 10 Oct 2025 10:18:46 +0200 Subject: [PATCH 02/24] tests for merge --- test/envirobly/config_test.rb | 12 ++++++++++++ test/fixtures/configs/deploy.staging.yml | 4 ++++ test/fixtures/configs/deploy.yml | 7 +++++++ test/fixtures/configs/ignored.txt | 1 + 4 files changed, 24 insertions(+) create mode 100644 test/fixtures/configs/ignored.txt diff --git a/test/envirobly/config_test.rb b/test/envirobly/config_test.rb index 5df1bce..cbb072f 100644 --- a/test/envirobly/config_test.rb +++ b/test/envirobly/config_test.rb @@ -12,4 +12,16 @@ class Envirobly::ConfigTest < ActiveSupport::TestCase } assert_equal expected, config.configs end + + test "merge without override" do + config = Envirobly::Config.new("test/fixtures/configs") + expected = <<~YAML + services: + YAML + assert_equal expected, config.merge + end + + test "merge with environ override" do + skip "todo" + end end diff --git a/test/fixtures/configs/deploy.staging.yml b/test/fixtures/configs/deploy.staging.yml index 6aab550..c60d76d 100644 --- a/test/fixtures/configs/deploy.staging.yml +++ b/test/fixtures/configs/deploy.staging.yml @@ -1,3 +1,7 @@ services: app: instance_type: t4g.micro + env: + <<: *shared_env + APP_ENV: staging + STAGING_VAR: abcd diff --git a/test/fixtures/configs/deploy.yml b/test/fixtures/configs/deploy.yml index c43214b..3230147 100644 --- a/test/fixtures/configs/deploy.yml +++ b/test/fixtures/configs/deploy.yml @@ -1,3 +1,10 @@ +x: + shared_env: &shared_env + VERSION: 1 + services: app: public: true + env: + <<: *shared_env + APP_ENV: production diff --git a/test/fixtures/configs/ignored.txt b/test/fixtures/configs/ignored.txt new file mode 100644 index 0000000..1e69222 --- /dev/null +++ b/test/fixtures/configs/ignored.txt @@ -0,0 +1 @@ +This file is ignored by Config class. From 439110225f4d7602c63513fe32ef064999832dcd Mon Sep 17 00:00:00 2001 From: Robert Starsi Date: Fri, 10 Oct 2025 10:30:26 +0200 Subject: [PATCH 03/24] merge without override --- lib/envirobly/config.rb | 16 ++++++++++++++++ test/envirobly/config_test.rb | 9 ++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/lib/envirobly/config.rb b/lib/envirobly/config.rb index 2900ed8..65f2d87 100644 --- a/lib/envirobly/config.rb +++ b/lib/envirobly/config.rb @@ -19,6 +19,22 @@ def configs end.compact.to_h end + def merge(environ_name = nil) + path = Pathname.new(DIR).join(BASE).to_s + yaml = configs.fetch(path) + base = YAML.safe_load yaml, aliases: true, symbolize_names: true + + if environ_name.present? + override_path = path.split("/").insert(1, environ_name).join("/") + + if configs.key?(override_path) + return configs.fetch(override_path) + end + end + + base + end + private def config_file?(file) file == BASE || file.match?(OVERRIDES_PATTERN) diff --git a/test/envirobly/config_test.rb b/test/envirobly/config_test.rb index cbb072f..02b5386 100644 --- a/test/envirobly/config_test.rb +++ b/test/envirobly/config_test.rb @@ -15,9 +15,12 @@ class Envirobly::ConfigTest < ActiveSupport::TestCase test "merge without override" do config = Envirobly::Config.new("test/fixtures/configs") - expected = <<~YAML - services: - YAML + expected = { + x: { shared_env: { VERSION: 1 } }, + services: { + app: { public: true, env: { VERSION: 1, APP_ENV: "production" } } + } + } assert_equal expected, config.merge end From e28ed9df0ca0174b229449879861bc73d17a1067 Mon Sep 17 00:00:00 2001 From: Robert Starsi Date: Fri, 10 Oct 2025 10:36:21 +0200 Subject: [PATCH 04/24] merge with environ override --- lib/envirobly/config.rb | 6 ++-- test/envirobly/config_test.rb | 35 ++++++++++++++++++++++-- test/fixtures/configs/deploy.staging.yml | 2 +- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/lib/envirobly/config.rb b/lib/envirobly/config.rb index 65f2d87..24c3271 100644 --- a/lib/envirobly/config.rb +++ b/lib/envirobly/config.rb @@ -25,10 +25,12 @@ def merge(environ_name = nil) base = YAML.safe_load yaml, aliases: true, symbolize_names: true if environ_name.present? - override_path = path.split("/").insert(1, environ_name).join("/") + override_path = Pathname.new(DIR).join("deploy.#{environ_name}.yml").to_s if configs.key?(override_path) - return configs.fetch(override_path) + other_yaml = configs.fetch(override_path) + override = YAML.safe_load other_yaml, aliases: true, symbolize_names: true + return base.deep_merge(override) end end diff --git a/test/envirobly/config_test.rb b/test/envirobly/config_test.rb index 02b5386..8d03257 100644 --- a/test/envirobly/config_test.rb +++ b/test/envirobly/config_test.rb @@ -16,15 +16,44 @@ class Envirobly::ConfigTest < ActiveSupport::TestCase test "merge without override" do config = Envirobly::Config.new("test/fixtures/configs") expected = { - x: { shared_env: { VERSION: 1 } }, + x: { + shared_env: { + VERSION: 1 + } + }, services: { - app: { public: true, env: { VERSION: 1, APP_ENV: "production" } } + app: { + public: true, + env: { + VERSION: 1, + APP_ENV: "production" + } + } } } assert_equal expected, config.merge end test "merge with environ override" do - skip "todo" + config = Envirobly::Config.new("test/fixtures/configs") + expected = { + x: { + shared_env: { + VERSION: 1 + } + }, + services: { + app: { + public: false, + instance_type: "t4g.micro", + env: { + VERSION: 1, + APP_ENV: "staging", + STAGING_VAR: "abcd" + } + } + } + } + assert_equal expected, config.merge("staging") end end diff --git a/test/fixtures/configs/deploy.staging.yml b/test/fixtures/configs/deploy.staging.yml index c60d76d..abda433 100644 --- a/test/fixtures/configs/deploy.staging.yml +++ b/test/fixtures/configs/deploy.staging.yml @@ -1,7 +1,7 @@ services: app: + public: false instance_type: t4g.micro env: - <<: *shared_env APP_ENV: staging STAGING_VAR: abcd From 9fc51f7fee0bc7a91e0a4bc1bc463026e7aa9632 Mon Sep 17 00:00:00 2001 From: Robert Starsi Date: Fri, 10 Oct 2025 10:37:40 +0200 Subject: [PATCH 05/24] config.errors --- lib/envirobly/config.rb | 3 +++ test/envirobly/config_test.rb | 2 ++ 2 files changed, 5 insertions(+) diff --git a/lib/envirobly/config.rb b/lib/envirobly/config.rb index 24c3271..7f2e529 100644 --- a/lib/envirobly/config.rb +++ b/lib/envirobly/config.rb @@ -5,8 +5,11 @@ class Envirobly::Config BASE = "deploy.yml" OVERRIDES_PATTERN = /deploy\.([a-z0-9\-_]+)\.yml/i + attr_reader :errors + def initialize(dir = DIR) @dir = Pathname.new dir + @errors = [] end def configs diff --git a/test/envirobly/config_test.rb b/test/envirobly/config_test.rb index 8d03257..3f4a8bf 100644 --- a/test/envirobly/config_test.rb +++ b/test/envirobly/config_test.rb @@ -32,6 +32,7 @@ class Envirobly::ConfigTest < ActiveSupport::TestCase } } assert_equal expected, config.merge + assert_empty config.errors end test "merge with environ override" do @@ -55,5 +56,6 @@ class Envirobly::ConfigTest < ActiveSupport::TestCase } } assert_equal expected, config.merge("staging") + assert_empty config.errors end end From c50fcac57c45249dea00a7f98244e5eeacab0876 Mon Sep 17 00:00:00 2001 From: Robert Starsi Date: Fri, 10 Oct 2025 10:39:22 +0200 Subject: [PATCH 06/24] refactor --- lib/envirobly/config.rb | 66 +++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/lib/envirobly/config.rb b/lib/envirobly/config.rb index 7f2e529..b8916e2 100644 --- a/lib/envirobly/config.rb +++ b/lib/envirobly/config.rb @@ -1,47 +1,49 @@ # frozen_string_literal: true -class Envirobly::Config - DIR = ".envirobly" - BASE = "deploy.yml" - OVERRIDES_PATTERN = /deploy\.([a-z0-9\-_]+)\.yml/i +module Envirobly + class Config + DIR = ".envirobly" + BASE = "deploy.yml" + OVERRIDES_PATTERN = /deploy\.([a-z0-9\-_]+)\.yml/i - attr_reader :errors + attr_reader :errors - def initialize(dir = DIR) - @dir = Pathname.new dir - @errors = [] - end + def initialize(dir = DIR) + @dir = Pathname.new dir + @errors = [] + end - def configs - Dir.entries(@dir).map do |file| - path = File.join(@dir, file) + def configs + Dir.entries(@dir).map do |file| + path = File.join(@dir, file) - next unless File.file?(path) && config_file?(file) + next unless File.file?(path) && config_file?(file) - [ "#{DIR}/#{file}", ERB.new(File.read(path)).result ] - end.compact.to_h - end + [ "#{DIR}/#{file}", ERB.new(File.read(path)).result ] + end.compact.to_h + end - def merge(environ_name = nil) - path = Pathname.new(DIR).join(BASE).to_s - yaml = configs.fetch(path) - base = YAML.safe_load yaml, aliases: true, symbolize_names: true + def merge(environ_name = nil) + path = Pathname.new(DIR).join(BASE).to_s + yaml = configs.fetch(path) + base = YAML.safe_load yaml, aliases: true, symbolize_names: true - if environ_name.present? - override_path = Pathname.new(DIR).join("deploy.#{environ_name}.yml").to_s + if environ_name.present? + override_path = Pathname.new(DIR).join("deploy.#{environ_name}.yml").to_s - if configs.key?(override_path) - other_yaml = configs.fetch(override_path) - override = YAML.safe_load other_yaml, aliases: true, symbolize_names: true - return base.deep_merge(override) + if configs.key?(override_path) + other_yaml = configs.fetch(override_path) + override = YAML.safe_load other_yaml, aliases: true, symbolize_names: true + return base.deep_merge(override) + end end + + base end - base + private + def config_file?(file) + file == BASE || file.match?(OVERRIDES_PATTERN) + end end - - private - def config_file?(file) - file == BASE || file.match?(OVERRIDES_PATTERN) - end end From 22d3f7144a91dcae3e6dd0503500a8088b1d1d71 Mon Sep 17 00:00:00 2001 From: Robert Starsi Date: Fri, 10 Oct 2025 11:32:31 +0200 Subject: [PATCH 07/24] expand --- test/envirobly/config_test.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/envirobly/config_test.rb b/test/envirobly/config_test.rb index 3f4a8bf..7cce2df 100644 --- a/test/envirobly/config_test.rb +++ b/test/envirobly/config_test.rb @@ -31,8 +31,12 @@ class Envirobly::ConfigTest < ActiveSupport::TestCase } } } + assert_equal expected, config.merge assert_empty config.errors + + assert_equal expected, config.merge("xyz"), "This override doens't exist" + assert_empty config.errors end test "merge with environ override" do From d3152aa87116a00ec3b5d60772ac6774d4d30596 Mon Sep 17 00:00:00 2001 From: Robert Starsi Date: Fri, 10 Oct 2025 11:36:17 +0200 Subject: [PATCH 08/24] ERB parsing --- lib/envirobly/config.rb | 6 +++--- test/fixtures/configs/deploy.staging.yml | 2 +- test/fixtures/configs/deploy.yml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/envirobly/config.rb b/lib/envirobly/config.rb index b8916e2..af3895d 100644 --- a/lib/envirobly/config.rb +++ b/lib/envirobly/config.rb @@ -19,21 +19,21 @@ def configs next unless File.file?(path) && config_file?(file) - [ "#{DIR}/#{file}", ERB.new(File.read(path)).result ] + [ "#{DIR}/#{file}", File.read(path) ] end.compact.to_h end def merge(environ_name = nil) path = Pathname.new(DIR).join(BASE).to_s yaml = configs.fetch(path) - base = YAML.safe_load yaml, aliases: true, symbolize_names: true + base = YAML.safe_load ERB.new(yaml).result, aliases: true, symbolize_names: true if environ_name.present? override_path = Pathname.new(DIR).join("deploy.#{environ_name}.yml").to_s if configs.key?(override_path) other_yaml = configs.fetch(override_path) - override = YAML.safe_load other_yaml, aliases: true, symbolize_names: true + override = YAML.safe_load ERB.new(other_yaml).result, aliases: true, symbolize_names: true return base.deep_merge(override) end end diff --git a/test/fixtures/configs/deploy.staging.yml b/test/fixtures/configs/deploy.staging.yml index abda433..17783fb 100644 --- a/test/fixtures/configs/deploy.staging.yml +++ b/test/fixtures/configs/deploy.staging.yml @@ -1,6 +1,6 @@ services: app: - public: false + public: <%= "false" if true %> instance_type: t4g.micro env: APP_ENV: staging diff --git a/test/fixtures/configs/deploy.yml b/test/fixtures/configs/deploy.yml index 3230147..de53184 100644 --- a/test/fixtures/configs/deploy.yml +++ b/test/fixtures/configs/deploy.yml @@ -4,7 +4,7 @@ x: services: app: - public: true + public: <%= "true" %> env: <<: *shared_env APP_ENV: production From 0346dcd1d96f2e3289f4ba732eb560d9716e9e20 Mon Sep 17 00:00:00 2001 From: Robert Starsi Date: Fri, 10 Oct 2025 11:37:20 +0200 Subject: [PATCH 09/24] refactor --- lib/envirobly/config.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/envirobly/config.rb b/lib/envirobly/config.rb index af3895d..25022e5 100644 --- a/lib/envirobly/config.rb +++ b/lib/envirobly/config.rb @@ -26,14 +26,14 @@ def configs def merge(environ_name = nil) path = Pathname.new(DIR).join(BASE).to_s yaml = configs.fetch(path) - base = YAML.safe_load ERB.new(yaml).result, aliases: true, symbolize_names: true + base = parse yaml if environ_name.present? override_path = Pathname.new(DIR).join("deploy.#{environ_name}.yml").to_s if configs.key?(override_path) other_yaml = configs.fetch(override_path) - override = YAML.safe_load ERB.new(other_yaml).result, aliases: true, symbolize_names: true + override = parse other_yaml return base.deep_merge(override) end end @@ -45,5 +45,9 @@ def merge(environ_name = nil) def config_file?(file) file == BASE || file.match?(OVERRIDES_PATTERN) end + + def parse(content) + YAML.safe_load ERB.new(content).result, aliases: true, symbolize_names: true + end end end From 88b20f2b66d55e4c5c72510765a2cee0fc6b40ea Mon Sep 17 00:00:00 2001 From: Robert Starsi Date: Fri, 10 Oct 2025 11:44:56 +0200 Subject: [PATCH 10/24] invalid YAML --- lib/envirobly/config.rb | 12 +++++++----- test/envirobly/config_test.rb | 8 ++++++++ test/fixtures/invalid_configs/deploy.erb-error.yml | 1 + test/fixtures/invalid_configs/deploy.yml | 2 ++ 4 files changed, 18 insertions(+), 5 deletions(-) create mode 100644 test/fixtures/invalid_configs/deploy.erb-error.yml create mode 100644 test/fixtures/invalid_configs/deploy.yml diff --git a/lib/envirobly/config.rb b/lib/envirobly/config.rb index 25022e5..78b59bd 100644 --- a/lib/envirobly/config.rb +++ b/lib/envirobly/config.rb @@ -26,19 +26,19 @@ def configs def merge(environ_name = nil) path = Pathname.new(DIR).join(BASE).to_s yaml = configs.fetch(path) - base = parse yaml + result = parse yaml, path if environ_name.present? override_path = Pathname.new(DIR).join("deploy.#{environ_name}.yml").to_s if configs.key?(override_path) other_yaml = configs.fetch(override_path) - override = parse other_yaml - return base.deep_merge(override) + override = parse other_yaml, override_path + result = result.deep_merge(override) end end - base + @errors.empty? ? result : nil end private @@ -46,8 +46,10 @@ def config_file?(file) file == BASE || file.match?(OVERRIDES_PATTERN) end - def parse(content) + def parse(content, path) YAML.safe_load ERB.new(content).result, aliases: true, symbolize_names: true + rescue Psych::Exception => e + @errors << { message: e.message, path: } end end end diff --git a/test/envirobly/config_test.rb b/test/envirobly/config_test.rb index 7cce2df..e159067 100644 --- a/test/envirobly/config_test.rb +++ b/test/envirobly/config_test.rb @@ -62,4 +62,12 @@ class Envirobly::ConfigTest < ActiveSupport::TestCase assert_equal expected, config.merge("staging") assert_empty config.errors end + + test "invalid YAML" do + config = Envirobly::Config.new("test/fixtures/invalid_configs") + assert_nil config.merge + assert_equal 1, config.errors.size + assert_equal "(): did not find expected node content while parsing a flow node at line 2 column 3", config.errors.first[:message] + assert_equal ".envirobly/deploy.yml", config.errors.first[:path] + end end diff --git a/test/fixtures/invalid_configs/deploy.erb-error.yml b/test/fixtures/invalid_configs/deploy.erb-error.yml new file mode 100644 index 0000000..76a7083 --- /dev/null +++ b/test/fixtures/invalid_configs/deploy.erb-error.yml @@ -0,0 +1 @@ +services: <% throw "ERB error" %> diff --git a/test/fixtures/invalid_configs/deploy.yml b/test/fixtures/invalid_configs/deploy.yml new file mode 100644 index 0000000..c789edd --- /dev/null +++ b/test/fixtures/invalid_configs/deploy.yml @@ -0,0 +1,2 @@ +invalid_yaml: { + - From aa2530547297afe05107340c96443218db4dbdde Mon Sep 17 00:00:00 2001 From: Robert Starsi Date: Fri, 10 Oct 2025 11:49:00 +0200 Subject: [PATCH 11/24] ERB error parsing --- lib/envirobly/config.rb | 11 +++++++++-- test/envirobly/config_test.rb | 9 +++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/lib/envirobly/config.rb b/lib/envirobly/config.rb index 78b59bd..675bf46 100644 --- a/lib/envirobly/config.rb +++ b/lib/envirobly/config.rb @@ -34,7 +34,7 @@ def merge(environ_name = nil) if configs.key?(override_path) other_yaml = configs.fetch(override_path) override = parse other_yaml, override_path - result = result.deep_merge(override) + result = result.deep_merge(override) if override.is_a?(Hash) end end @@ -47,7 +47,14 @@ def config_file?(file) end def parse(content, path) - YAML.safe_load ERB.new(content).result, aliases: true, symbolize_names: true + begin + yaml = ERB.new(content).result + rescue Exception => e + @errors << { message: e.message, path: } + return + end + + YAML.safe_load yaml, aliases: true, symbolize_names: true rescue Psych::Exception => e @errors << { message: e.message, path: } end diff --git a/test/envirobly/config_test.rb b/test/envirobly/config_test.rb index e159067..158f9a6 100644 --- a/test/envirobly/config_test.rb +++ b/test/envirobly/config_test.rb @@ -70,4 +70,13 @@ class Envirobly::ConfigTest < ActiveSupport::TestCase assert_equal "(): did not find expected node content while parsing a flow node at line 2 column 3", config.errors.first[:message] assert_equal ".envirobly/deploy.yml", config.errors.first[:path] end + + test "invalid ERB" do + config = Envirobly::Config.new("test/fixtures/invalid_configs") + assert_nil config.merge("erb-error") + assert_equal 2, config.errors.size + assert_equal ".envirobly/deploy.yml", config.errors.first[:path] + assert_equal ".envirobly/deploy.erb-error.yml", config.errors.second[:path] + assert_equal "uncaught throw \"ERB error\"", config.errors.second[:message] + end end From 98700533198abee8db3da18443a211bb32ea5d99 Mon Sep 17 00:00:00 2001 From: Robert Starsi Date: Fri, 10 Oct 2025 11:59:32 +0200 Subject: [PATCH 12/24] Secret --- lib/envirobly/config.rb | 2 +- lib/envirobly/secret.rb | 27 +++++++++++++++++++++++++++ test/envirobly/config_test.rb | 8 ++++---- test/fixtures/configs/deploy.yml | 2 +- 4 files changed, 33 insertions(+), 6 deletions(-) create mode 100644 lib/envirobly/secret.rb diff --git a/lib/envirobly/config.rb b/lib/envirobly/config.rb index 675bf46..10e286c 100644 --- a/lib/envirobly/config.rb +++ b/lib/envirobly/config.rb @@ -54,7 +54,7 @@ def parse(content, path) return end - YAML.safe_load yaml, aliases: true, symbolize_names: true + YAML.safe_load yaml, aliases: true, symbolize_names: true, permitted_classes: [ Secret ] rescue Psych::Exception => e @errors << { message: e.message, path: } end diff --git a/lib/envirobly/secret.rb b/lib/envirobly/secret.rb new file mode 100644 index 0000000..401bf76 --- /dev/null +++ b/lib/envirobly/secret.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module Envirobly + class Secret + attr_reader :plain + + def initialize(value) + @plain = value + end + + def init_with(coder) + @plain = coder.scalar + end + + def encode_with(coder) + coder.scalar = @plain + end + + def to_s + "[SECRET]" + end + + def ==(other) + other.is_a?(Secret) && other.plain == plain + end + end +end diff --git a/test/envirobly/config_test.rb b/test/envirobly/config_test.rb index 158f9a6..0a2191f 100644 --- a/test/envirobly/config_test.rb +++ b/test/envirobly/config_test.rb @@ -18,14 +18,14 @@ class Envirobly::ConfigTest < ActiveSupport::TestCase expected = { x: { shared_env: { - VERSION: 1 + SECRET: Envirobly::Secret.new("mySecret") } }, services: { app: { public: true, env: { - VERSION: 1, + SECRET: Envirobly::Secret.new("mySecret"), APP_ENV: "production" } } @@ -44,7 +44,7 @@ class Envirobly::ConfigTest < ActiveSupport::TestCase expected = { x: { shared_env: { - VERSION: 1 + SECRET: Envirobly::Secret.new("mySecret") } }, services: { @@ -52,7 +52,7 @@ class Envirobly::ConfigTest < ActiveSupport::TestCase public: false, instance_type: "t4g.micro", env: { - VERSION: 1, + SECRET: Envirobly::Secret.new("mySecret"), APP_ENV: "staging", STAGING_VAR: "abcd" } diff --git a/test/fixtures/configs/deploy.yml b/test/fixtures/configs/deploy.yml index de53184..f5629e8 100644 --- a/test/fixtures/configs/deploy.yml +++ b/test/fixtures/configs/deploy.yml @@ -1,6 +1,6 @@ x: shared_env: &shared_env - VERSION: 1 + SECRET: !secret mySecret services: app: From d0409c5e4f71a1182a846cdf8f3cd5857da0dfc8 Mon Sep 17 00:00:00 2001 From: Robert Starsi Date: Fri, 10 Oct 2025 12:03:17 +0200 Subject: [PATCH 13/24] secrets working --- lib/envirobly/secret.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/envirobly/secret.rb b/lib/envirobly/secret.rb index 401bf76..55c2b8c 100644 --- a/lib/envirobly/secret.rb +++ b/lib/envirobly/secret.rb @@ -25,3 +25,5 @@ def ==(other) end end end + +YAML.add_tag("!secret", Envirobly::Secret) From ef0ae0e686c6f1851445c03687ced4f9e10f0178 Mon Sep 17 00:00:00 2001 From: Robert Starsi Date: Fri, 10 Oct 2025 12:05:29 +0200 Subject: [PATCH 14/24] secret test --- test/envirobly/secret_test.rb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 test/envirobly/secret_test.rb diff --git a/test/envirobly/secret_test.rb b/test/envirobly/secret_test.rb new file mode 100644 index 0000000..83bbb51 --- /dev/null +++ b/test/envirobly/secret_test.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +require "test_helper" + +module Envirobly + class SecretTest < ActiveSupport::TestCase + test "equality" do + secret1 = Secret.new("a") + secret2 = Secret.new("a") + assert_equal secret1, secret2 + + secret2 = Secret.new("b") + assert_not_equal secret1, secret2 + end + end +end From 23abb81c541cc17af84b6227112016b6edab4a1e Mon Sep 17 00:00:00 2001 From: Robert Starsi Date: Fri, 10 Oct 2025 12:07:25 +0200 Subject: [PATCH 15/24] expand --- test/envirobly/secret_test.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/envirobly/secret_test.rb b/test/envirobly/secret_test.rb index 83bbb51..3dd70d4 100644 --- a/test/envirobly/secret_test.rb +++ b/test/envirobly/secret_test.rb @@ -12,5 +12,12 @@ class SecretTest < ActiveSupport::TestCase secret2 = Secret.new("b") assert_not_equal secret1, secret2 end + + test "dump" do + yaml = { + secret: Secret.new("hello") + }.to_yaml + assert_equal "---\n:secret: !secret hello\n", yaml + end end end From de009f3ce7f492122282ec12f5f8bc9422816fcd Mon Sep 17 00:00:00 2001 From: Robert Starsi Date: Fri, 10 Oct 2025 12:17:02 +0200 Subject: [PATCH 16/24] do not symbolize keys --- lib/envirobly/config.rb | 2 +- lib/envirobly/deployment.rb | 2 +- test/envirobly/config_test.rb | 40 +++++++++++++++++------------------ 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/lib/envirobly/config.rb b/lib/envirobly/config.rb index 10e286c..4568c81 100644 --- a/lib/envirobly/config.rb +++ b/lib/envirobly/config.rb @@ -54,7 +54,7 @@ def parse(content, path) return end - YAML.safe_load yaml, aliases: true, symbolize_names: true, permitted_classes: [ Secret ] + YAML.safe_load yaml, aliases: true, permitted_classes: [ Secret ] rescue Psych::Exception => e @errors << { message: e.message, path: } end diff --git a/lib/envirobly/deployment.rb b/lib/envirobly/deployment.rb index 88bbc88..37b5685 100644 --- a/lib/envirobly/deployment.rb +++ b/lib/envirobly/deployment.rb @@ -53,7 +53,7 @@ def initialize(environ_name:, commit:, account_id:, project_name:, project_id:, commit_time: @commit.time, commit_message: @commit.message, object_tree_checksum: @commit.object_tree_checksum, - configs: @config.configs + config: @config.merge(@environ_name) } } end diff --git a/test/envirobly/config_test.rb b/test/envirobly/config_test.rb index 0a2191f..b8eb89a 100644 --- a/test/envirobly/config_test.rb +++ b/test/envirobly/config_test.rb @@ -16,17 +16,17 @@ class Envirobly::ConfigTest < ActiveSupport::TestCase test "merge without override" do config = Envirobly::Config.new("test/fixtures/configs") expected = { - x: { - shared_env: { - SECRET: Envirobly::Secret.new("mySecret") + "x" => { + "shared_env" => { + "SECRET" => Envirobly::Secret.new("mySecret") } }, - services: { - app: { - public: true, - env: { - SECRET: Envirobly::Secret.new("mySecret"), - APP_ENV: "production" + "services" => { + "app" => { + "public" => true, + "env" => { + "SECRET" => Envirobly::Secret.new("mySecret"), + "APP_ENV" => "production" } } } @@ -42,19 +42,19 @@ class Envirobly::ConfigTest < ActiveSupport::TestCase test "merge with environ override" do config = Envirobly::Config.new("test/fixtures/configs") expected = { - x: { - shared_env: { - SECRET: Envirobly::Secret.new("mySecret") + "x" => { + "shared_env" => { + "SECRET" => Envirobly::Secret.new("mySecret") } }, - services: { - app: { - public: false, - instance_type: "t4g.micro", - env: { - SECRET: Envirobly::Secret.new("mySecret"), - APP_ENV: "staging", - STAGING_VAR: "abcd" + "services" => { + "app" => { + "public" => false, + "instance_type" => "t4g.micro", + "env" => { + "SECRET" => Envirobly::Secret.new("mySecret"), + "APP_ENV" => "staging", + "STAGING_VAR" => "abcd" } } } From 6d8715dcd141458c1bf4e7176d517c1de20b2d99 Mon Sep 17 00:00:00 2001 From: Robert Starsi Date: Fri, 10 Oct 2025 12:21:21 +0200 Subject: [PATCH 17/24] deploy uses config.merge --- lib/envirobly/deployment.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/envirobly/deployment.rb b/lib/envirobly/deployment.rb index 37b5685..2ad1c4a 100644 --- a/lib/envirobly/deployment.rb +++ b/lib/envirobly/deployment.rb @@ -59,13 +59,15 @@ def initialize(environ_name:, commit:, account_id:, project_name:, project_id:, end def perform(dry_run:) + puts green("This is a dry run, nothing will be deployed.") puts [ "Deploying commit", yellow(@commit.short_ref), faint("→"), green(@environ_name) ].join(" ") puts puts " #{@commit.message}" puts if dry_run - puts YAML.dump(@params) + puts green("Your config:") + puts YAML.dump(@params[:deployment][:config]) return end From 3db63cf0e93df4ffbe138268bc357470af0505a0 Mon Sep 17 00:00:00 2001 From: Robert Starsi Date: Fri, 10 Oct 2025 12:28:05 +0200 Subject: [PATCH 18/24] dry run targetting table --- lib/envirobly/deployment.rb | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/envirobly/deployment.rb b/lib/envirobly/deployment.rb index 2ad1c4a..174d985 100644 --- a/lib/envirobly/deployment.rb +++ b/lib/envirobly/deployment.rb @@ -6,7 +6,7 @@ module Envirobly class Deployment include Colorize - attr_reader :params + attr_reader :params, :shell def initialize(environ_name:, commit:, account_id:, project_name:, project_id:, region:, shell:) @commit = commit @@ -59,7 +59,7 @@ def initialize(environ_name:, commit:, account_id:, project_name:, project_id:, end def perform(dry_run:) - puts green("This is a dry run, nothing will be deployed.") + shell.say "This is a dry run, nothing will be deployed.", :green puts [ "Deploying commit", yellow(@commit.short_ref), faint("→"), green(@environ_name) ].join(" ") puts puts " #{@commit.message}" @@ -68,6 +68,20 @@ def perform(dry_run:) if dry_run puts green("Your config:") puts YAML.dump(@params[:deployment][:config]) + + shell.say + shell.say "Targeting:", :green + + targets_and_values = [ + [ "Account ID", @params[:account_id].to_s ], + [ "Project ID", @params[:project_id].to_s ], + [ "Region", @params[:region] ], + [ "Project Name", @params[:project_name] ], + [ "Environ Name", @params[:deployment][:environ_name] ] + ] + + shell.print_table targets_and_values, borders: true + return end From ed08fe3db8912211f4aa71f84b13c4329af6c1b7 Mon Sep 17 00:00:00 2001 From: Robert Starsi Date: Fri, 10 Oct 2025 12:28:16 +0200 Subject: [PATCH 19/24] note --- lib/envirobly/deployment.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/envirobly/deployment.rb b/lib/envirobly/deployment.rb index 174d985..42edb64 100644 --- a/lib/envirobly/deployment.rb +++ b/lib/envirobly/deployment.rb @@ -60,6 +60,8 @@ def initialize(environ_name:, commit:, account_id:, project_name:, project_id:, def perform(dry_run:) shell.say "This is a dry run, nothing will be deployed.", :green + + # TODO: Replace with shell puts [ "Deploying commit", yellow(@commit.short_ref), faint("→"), green(@environ_name) ].join(" ") puts puts " #{@commit.message}" From 2c76aaa4b38b5de89b92a3fd01ad0fa7cc880904 Mon Sep 17 00:00:00 2001 From: Robert Starsi Date: Fri, 10 Oct 2025 12:28:41 +0200 Subject: [PATCH 20/24] note --- lib/envirobly/deployment.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/envirobly/deployment.rb b/lib/envirobly/deployment.rb index 42edb64..6f43865 100644 --- a/lib/envirobly/deployment.rb +++ b/lib/envirobly/deployment.rb @@ -64,6 +64,7 @@ def perform(dry_run:) # TODO: Replace with shell puts [ "Deploying commit", yellow(@commit.short_ref), faint("→"), green(@environ_name) ].join(" ") puts + # TODO: Multiline indent puts " #{@commit.message}" puts From 9e651b2a3963427d206d3cfbf5917156b8cb612c Mon Sep 17 00:00:00 2001 From: Robert Starsi Date: Fri, 10 Oct 2025 12:30:22 +0200 Subject: [PATCH 21/24] copy --- lib/envirobly/deployment.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/envirobly/deployment.rb b/lib/envirobly/deployment.rb index 6f43865..37ede9f 100644 --- a/lib/envirobly/deployment.rb +++ b/lib/envirobly/deployment.rb @@ -69,7 +69,7 @@ def perform(dry_run:) puts if dry_run - puts green("Your config:") + puts green("Config:") puts YAML.dump(@params[:deployment][:config]) shell.say From b359e95976e31928c51f5879e8d1fc73a51443e8 Mon Sep 17 00:00:00 2001 From: Robert Starsi Date: Fri, 10 Oct 2025 12:31:04 +0200 Subject: [PATCH 22/24] bump v --- Gemfile.lock | 2 +- lib/envirobly/version.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index b49b42a..7bd508e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - envirobly (1.9.0) + envirobly (1.10.0) activesupport (~> 8.0) aws-sdk-s3 (~> 1.182) concurrent-ruby (~> 1.3) diff --git a/lib/envirobly/version.rb b/lib/envirobly/version.rb index 2f4fae9..9dacd60 100644 --- a/lib/envirobly/version.rb +++ b/lib/envirobly/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Envirobly - VERSION = "1.9.0" + VERSION = "1.10.0" end From 55fc6a9b6c30ddda5b8f890d24b3101b16f176ad Mon Sep 17 00:00:00 2001 From: Robert Starsi Date: Fri, 10 Oct 2025 13:44:00 +0200 Subject: [PATCH 23/24] adjust validation --- lib/envirobly/cli/main.rb | 6 +++--- lib/envirobly/deployment.rb | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/envirobly/cli/main.rb b/lib/envirobly/cli/main.rb index 8bfbf75..78ba6d0 100644 --- a/lib/envirobly/cli/main.rb +++ b/lib/envirobly/cli/main.rb @@ -36,14 +36,14 @@ def set_default_region Envirobly::Defaults::Region.new(shell:).require_value end - desc "validate", "Validates config" - def validate + desc "validate", "Validates config (for given environ)" + def validate(environ_name = nil) Envirobly::AccessToken.new(shell:).require! config = Envirobly::Config.new api = Envirobly::Api.new - params = { validation: { configs: config.configs } } + params = { validation: { config: config.merge(environ_name).to_yaml } } api.validate_shape params say "Config is valid #{green_check}" diff --git a/lib/envirobly/deployment.rb b/lib/envirobly/deployment.rb index 37ede9f..0a0095e 100644 --- a/lib/envirobly/deployment.rb +++ b/lib/envirobly/deployment.rb @@ -53,7 +53,7 @@ def initialize(environ_name:, commit:, account_id:, project_name:, project_id:, commit_time: @commit.time, commit_message: @commit.message, object_tree_checksum: @commit.object_tree_checksum, - config: @config.merge(@environ_name) + config: @config.merge(@environ_name).to_yaml } } end @@ -70,7 +70,7 @@ def perform(dry_run:) if dry_run puts green("Config:") - puts YAML.dump(@params[:deployment][:config]) + puts @params[:deployment][:config] shell.say shell.say "Targeting:", :green From 7ab785f3dc41d3a51c527b9b99a0b66bd9e7158c Mon Sep 17 00:00:00 2001 From: Robert Starsi Date: Fri, 10 Oct 2025 13:46:53 +0200 Subject: [PATCH 24/24] fix --- lib/envirobly/deployment.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/envirobly/deployment.rb b/lib/envirobly/deployment.rb index 0a0095e..db74e09 100644 --- a/lib/envirobly/deployment.rb +++ b/lib/envirobly/deployment.rb @@ -59,7 +59,9 @@ def initialize(environ_name:, commit:, account_id:, project_name:, project_id:, end def perform(dry_run:) - shell.say "This is a dry run, nothing will be deployed.", :green + if dry_run + shell.say "This is a dry run, nothing will be deployed.", :green + end # TODO: Replace with shell puts [ "Deploying commit", yellow(@commit.short_ref), faint("→"), green(@environ_name) ].join(" ")